Singing Contest
题意:有2^n个歌手进行比赛,每位歌手准备好了n首歌,每首歌的愉悦度都不一样,每位歌手都知道对方每首歌的愉悦度,并且愉悦度越高的就会赢,输了的直接淘汰,为了尽可能的多进行几场比赛(赛制为两两相互比赛),
思路:歌手每场都会从低到高选出第一个大于对方歌手的歌来进行比赛,对于选值操作在judge函数里,我用的是二分查找的lower_bound()函数,每场输了的人直接将他的vis置为0,赢了的歌手所场完的歌则将它的愉悦度置为-1,然后每次进行judge()操作时都要进行sort排序,愉悦度为-1的歌直接排在前面,对后续的比赛不会影响。
1 #include<bits/stdc++.h> 2 using namespace std; 3 typedef long long int LL; 4 const int maxn=2e5+10; 5 int vis[maxn]; 6 LL m,n,k; 7 struct node 8 { 9 LL a[30]; LL mx; 10 } G[maxn]; 11 void judge(int x,int y) 12 { 13 LL flag; 14 sort(G[x].a,G[x].a+n); 15 sort(G[y].a,G[y].a+n); 16 G[x].mx=G[x].a[n-1]; 17 G[y].mx=G[y].a[n-1]; 18 if(G[x].mx>G[y].mx){ 19 flag=upper_bound(G[x].a,G[x].a+n,G[y].mx)-G[x].a; 20 G[x].a[flag]=-1; 21 vis[y]=0; 22 } 23 else{ 24 flag=upper_bound(G[y].a,G[y].a+n,G[x].mx)-G[y].a; 25 G[y].a[flag]=-1; 26 vis[x]=0; 27 } 28 } 29 int main() 30 { 31 int T; 32 int Case=0; 33 scanf("%lld",&T); 34 while(T--){ 35 scanf("%lld",&n); 36 int total=pow(2,n); 37 for(int i=1;i<=total;i++){ 38 for(int j=0;j<n;j++) 39 scanf("%lld",&G[i].a[j]); 40 vis[i]=1; 41 } 42 int num=0,k=n; 43 while(k--){ 44 num=0; 45 for(int i=1;i<=total;i++){ 46 if(num!=0&&vis[i]){ 47 judge(num,i); 48 num=0; 49 continue; 50 } 51 if(vis[i]==1) 52 num=i; 53 } 54 } 55 for(int i=1;i<=total;i++){ 56 if(vis[i]){ 57 printf("Case #%d: %d\n",++Case,i); 58 break; 59 } 60 } 61 } 62 return 0; 63 }