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 }

 

posted @ 2020-11-14 11:12  古比  阅读(567)  评论(0编辑  收藏  举报