2018.8.4牛客网暑期ACM训练第六场 A题

题目链接:https://www.nowcoder.com/acm/contest/144/A

题目大意:有2^n个歌手,每个歌手会准备n首歌去唱,每首歌有它的分数,分数高的就赢。两两相比,赢的人继续两两相比,直到冠军出来。

 

分析:用一个二维数组保存每个比赛歌手准备的歌曲,并且用该数组继续保存每轮胜者还可以唱的歌曲。可以知道,每个歌手要保证自己每场都赢,就要用比对手最高分歌曲还高的歌曲唱,并且在符合上述条件下,尽量选择分低的(贪心)。

#include<iostream>
using namespace std;
#include<cmath>
#include <algorithm>
#include<cstring>
#include<algorithm>
int a[20000][20];
int main()
{
	int t;
	cin>>t;
	int k=1;
	while(t--){
		int n;
		cin>>n;
		int num=pow(2,n); 
		for(int i=0;i<num;i++){
			for(int j=0;j<n;j++)
				cin>>a[i][j];
			a[i][n]=i+1;	//这里用a[i][n]来保存选手序号,因为下面每次去比,选手的序号和它在                
                               //二维数组第一维的坐标是不一样的,所以特别记录一下
		}
		for(int i=0;i<num;i++)
			sort(a[i],a[i]+n);	    //排序
		while(1){
			int k=0;
			for(int i=0;i<num;i+=2){
			if(a[i][n-1]>a[i+1][n-1]){
				for(int j=0;j<n;j++){
					if(a[i][j]>a[i+1][n-1]){
						a[i][j]=-1;	    //标记已经唱过的歌曲
  						break;
					}
				}
				int b=0;
				for(int j=0;j<=n;j++){    //覆盖
					if(a[i][j]!=-1)			
						a[i/2][b++]=a[i][j];
				}
			}else{
				for(int j=0;j<n;j++){
					if(a[i+1][j]>a[i][n-1]){
						a[i+1][j]=-1;
						break;
					}
				}
				int b=0;
				for(int j=0;j<=n;j++){
					if(a[i+1][j]!=-1)			
						a[i/2][b++]=a[i+1][j];
				}
		}
 	}
 	num/=2;
 	if(num==1)	break;	// n==1时,冠军就出来了
 	n=n-1;
}
	printf("Case #%d: %d\n",k++,a[0][0]);	//最后的情况下,数组里只有选手序号了					
                                            
}
return 0;
}

猜你喜欢

转载自blog.csdn.net/qq_40725780/article/details/81429760