洛谷P1309 瑞士輪
阿新 • • 發佈:2017-11-09
turn 瑞士 比賽 lap main stream aps 編號 http
傳送門
題目大意:
2*n個人,有初始的比賽分數和實力值。
每次比賽前總分從大到小排序,總分相同編號小的排在前面。
每次比賽是1和2比,3和4比,5和6比。
實力值大的獲勝得1分。
每次比賽前排序確定比賽順序。
題解:
模擬60
哎呀忘記最後一次排序
#include<iostream> #include<cstdio> #include<cstring> #include<algorithm> #define N 200007 using namespace std; int n,r,q,t; struct P{ int id,sc,h; }a[N];60bool cmp(P a,P b){ if(a.sc==b.sc)return a.id<b.id; return a.sc>b.sc; } int main(){ scanf("%d%d%d",&n,&r,&q);t=n;n*=2; for(int i=1;i<=n;i++){ scanf("%d",&a[i].sc); a[i].id=i; } for(int i=1;i<=n;i++)scanf("%d",&a[i].h); for(inti=1;i<=r;i++){ sort(a+1,a+n+1,cmp); for(int i=1;i<=t;i++){ if(a[2*i].h>a[2*i-1].h)a[2*i].sc++; else a[2*i-1].sc++; } } sort(a+1,a+n+1,cmp); printf("%d\n",a[q].id); return 0; }
正解:模擬+歸並排序
60分做法時間復雜度是O()
sort的時間復雜度nlogn的
可以發現,在進行一輪比賽之後
勝的隊伍+1,
敗的隊伍不變
所以勝的隊伍的大小關系不變,敗的隊伍大小關系不變。
那麽把每一輪勝的隊伍和敗的隊伍分比放在一個數組裏
像歸並排序一樣並起來。由於兩個數組已經是有序的了,
所以排序的時間復雜度是O(n)的。
優化前O(r*nlogn+r*n),優化後O(2rn)
#include<iostream> #include<cstdio> #include<cstring> #include<algorithm> #define N 200007 using namespace std; int n,r,q,t,win,lose; struct P{ int id,sc,h; }a[N],w[N],l[N]; bool cmp(P a,P b){ if(a.sc==b.sc)return a.id<b.id; return a.sc>b.sc; } bool Cp(int c1,int c2,int id1,int id2){ if(c1>c2)return true; if(c1==c2&&id1<id2)return true; return false; } void merge(int ll,int rr){ int l1=ll,l2=ll,k=ll; while(l1<=rr&&l2<=rr){ if(Cp(w[l1].sc,l[l2].sc,w[l1].id,l[l2].id))a[k++]=w[l1++]; else a[k++]=l[l2++]; } while(l1<=rr)a[k++]=w[l1++]; while(l2<=rr)a[k++]=l[l2++]; } int main(){ scanf("%d%d%d",&n,&r,&q);t=n;n*=2; for(int i=1;i<=n;i++){ scanf("%d",&a[i].sc); a[i].id=i; } for(int i=1;i<=n;i++)scanf("%d",&a[i].h); sort(a+1,a+n+1,cmp); for(int i=1;i<=r;i++){ win=0;lose=0; for(int j=1;j<=t;j++){ if(a[j*2].h>a[j*2-1].h)w[++win]=a[j*2],w[win].sc++,l[++lose]=a[j*2-1]; else w[++win]=a[j*2-1],w[win].sc++,l[++lose]=a[j*2]; } merge(1,t); } printf("%d\n",a[q].id); return 0; }AC
洛谷P1309 瑞士輪