题目链接:https://www.luogu.org/problemnew/show/P1309
不得不说,真是一道很nice的题。极大助于理解归并排序的本质(其实就是两个有序表的依次对比合并加入而已)(貌似库函数有个merge函数这里说了。。)
快速排序快(适用于整个序列无序较多的情况下)
归并排序(适用于序列大多有序的情况,更快。因为基本有序时sort还要打乱再排所以很浪费时间,归并就快多了每次顺序合并即可)
对于本题,两个序列本来就是有序的(赢的一组,数的一组,肯定依次递降),就省去了归的步骤,直接进行并(合并)就行了,所以效率很高。
1 #include <iostream> 2 #include <string> 3 #include <algorithm> 4 #include <iomanip> 5 #include <cstdio> 6 #include <cstring> 7 using namespace std; 8 const int maxn=1e6+5; 9 typedef long long ll; 10 typedef unsigned long long ull; 11 int n,r,q; 12 struct px 13 { 14 int s; 15 int w; 16 int ii; 17 }T[maxn],temp[maxn],a[maxn],b[maxn]; 18 bool cmp(px aa,px bb) 19 { 20 if(aa.s!=bb.s) return aa.s>bb.s; 21 return aa.ii<bb.ii; 22 } 23 24 void MArray() 25 { 26 int i=1,j=1; 27 int k=1; 28 29 while(i<=n && j<=n) 30 { 31 if(a[i].s>b[j].s) temp[k++]=a[i++]; 32 else if(a[i].s<b[j].s) temp[k++]=b[j++]; 33 else 34 { 35 if(a[i].ii<b[j].ii) temp[k++]=a[i++]; 36 else temp[k++]=b[j++]; 37 } 38 } 39 40 while(i<=n) temp[k++]=a[i++]; 41 while(j<=n) temp[k++]=b[j++]; 42 43 for(int i=1;i<=k-1;i++) T[i]=temp[i];//更新原数组,为了下次再利用 44 } 45 46 47 int main() 48 { 49 ios::sync_with_stdio(false); cin.tie(0); 50 51 cin>>n>>r>>q; 52 for(int i=1;i<=n*2;i++) 53 { 54 cin>>T[i].s; 55 T[i].ii=i; 56 } 57 for(int i=1;i<=n*2;i++) cin>>T[i].w; 58 59 sort(T+1,T+1+n*2,cmp); 60 //for(int i=1;i<=n*2;i++) cout<<T[i].ii<<' '<<T[i].s<<' '<<T[i].w<<endl; 61 while(r--) 62 { 63 int p1=1,p2=1; 64 for(int i=1;i<=n*2;i+=2) 65 { 66 if(T[i].w>T[i+1].w) 67 { 68 T[i].s++; 69 a[p1++]=T[i]; 70 b[p2++]=T[i+1]; 71 } 72 else 73 { 74 T[i+1].s++; 75 a[p1++]=T[i+1]; 76 b[p2++]=T[i]; 77 } 78 } 79 MArray(); 80 //for(int i=1;i<=n*2;i++) cout<<T[i].ii<<' '<<T[i].s<<' '<<T[i].w<<endl; 81 } 82 83 cout<<T[q].ii<<endl; 84 85 return 0; 86 }
完。