Newcoder 144 A.Singing Contest(set)

186 篇文章 0 订阅

Description

一场比赛有 2 n 2^n 2n名参赛选手,每一轮选手按顺序两两 P K PK PK,胜者进入下一轮, n n n轮后选出冠军,每位选手至多表演 n n n轮,有 n n n首不同表现力的作品,两位选手中作品表现好的晋级,每位选手都知道其他选手的作品表现力,且每次可以自主选择要表现的作品,问所有选手都采取最合理策略的前提下,谁是冠军

Input

第一行一整数 T T T表示用例组数,每组用例首先输入一整数 n n n表示比赛轮数,之后 2 n 2^n 2n行每行 n n n个整数 a i , j a_{i,j} ai,j表示这位选手准备的 n n n个作品的表现力, a i , j a_{i,j} ai,j互不相同

( 1 ≤ T ≤ 10 , 1 ≤ n ≤ 14 , 1 ≤ a i , j ≤ 1 0 9 ) (1\le T\le 10,1\le n\le 14,1\le a_{i,j}\le 10^9) (1T10,1n14,1ai,j109)

Output

输出最终获胜者的编号

Sample Input

2
1
1
2
2
1 8
2 7
3 4
5 6

Sample Output

Case #1: 2
Case #2: 4

Solution

两位选手显然谁最高分高谁赢,赢的选手显然会拿比对方最高分高的最低分去比,用 s e t set set维护每位选手剩余的分数,每次两两比较维护胜者编号即可

Code

#include<cstdio>
#include<set>
using namespace std;
#define maxn (1<<14)+5
int T,n,a[maxn];
set<int>s[maxn]; 
set<int>::iterator it1,it2;
int main()
{
	scanf("%d",&T);
	int Case=1;
	while(T--)
	{
		scanf("%d",&n);
		int N=(1<<n);
		for(int i=1;i<=N;i++)
		{
			a[i]=i;
			s[i].clear();
			for(int j=0;j<n;j++)
			{
				int temp;
				scanf("%d",&temp);
				s[i].insert(temp);
			}
		}
		for(int k=1;k<=n;k++,N/=2)
		{
			for(int i=1;i<=N;i+=2)
			{
				it1=s[a[i]].end();
				it2=s[a[i+1]].end();
				it1--,it2--;
				if(*it1<*it2)
				{
					s[a[i+1]].erase(s[a[i+1]].lower_bound(*it1));
					a[(i+1)/2]=a[i+1];
				}
				else
				{
					s[a[i]].erase(s[a[i]].lower_bound(*it2));
					a[(i+1)/2]=a[i];
				}
			}
		}
		printf("Case #%d: %d\n",Case++,a[1]);
	}
	return 0;
}

评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值