Knockout Tournament

来源:互联网 发布:mac 删除文件 命令 编辑:程序博客网 时间:2024/06/05 06:29

Knockout Tournament 


In a knockout tournament there are 2 n players. One loss and a player is out of the tournament. Winners then play each other with the new winners advancing until there is only one winner left. If we number the players 1, 2, 3, . . . , 2 n, with the first round pairings 2k-1 vs 2k, for k = 1, 2, . . . , 2 (n-1), then we could give the results of the tournament in a complete binary tree. The winners are indicated in the interior nodes of the tree. Below is an example of a tournament with n = 3. 

After the tournament, some reporters were arguing about the relative ranking of the players, as determined by the tournament results. It's assumed that if player A beats player B who in turn beats player C, that player A will also beat player C; that is, winning is transitive. Now there is no doubt who the best player is. The question is what is the highest ranking a player can reasonably claim as a result of the tournament and what is the worst ranking a player can have, as a result of the tournament? For example, in the above tournament player 2, having lost to the eventual winner, could claim to be the 2nd best player in the field, but could well be the worst (ranked 8th). Player 5 could claim to be as high as 3rd (having lost to someone who could be 2nd) but no worse than 7th (having beaten one player in the 1st round). 
You are to determine the highest and lowest possible rankings of a set of players in the field, given the results of the tournament. 
Input
There will be multiple input instances. The input for each instance consists of three lines. The first line will contain a positive integer n < 8, indicating there are 2 n players in the tournament, numbered 1 through 2 n, paired in the manner indicated above. A value of n = 0 indicates end of input. The next line will contain the results of each round of the tournament (listed left-to-right) starting with the 1st round. For example, the tournament above would be given by 
1 3 5 8 1 8 1 
The final line of input for each instance will be a positive integer m followed by integers k1, ..., km, where each ki is a player in the field. 
Output
For each ki, issue one line of output of the form: 
Player ki can be ranked as high as h or as low as l. 
where you supply the appropriate numbers. These lines should appear in the same order as the ki did in the input. Output for problem instances should be separated with a blank line. 
Sample Input
31 3 5 8 1 8 12 2 542 3 6 7 9 11 14 15 3 6 9 15 6 9 64 1 15 7 60
Sample Output
Player 2 can be ranked as high as 2 or as low as 8.Player 5 can be ranked as high as 3 or as low as 7.Player 1 can be ranked as high as 4 or as low as 16.Player 15 can be ranked as high as 3 or as low as 13.Player 7 can be ranked as high as 2 or as low as 15.Player 6 can be ranked as high as 1 or as low as 1.

题意:给一个比赛的图,计算给定的人的最高排名和最低排名是多少;

分析:第一个实例,2虽然在第一场就被1打败,但是1是这里面最强的,所以2最高排名可能是2,又因为2在第一场就输了,并没有打败任何人,所以2最低排名可能是8.

5,被8打败,8最高排第二,所以5最高排第3,又因为5打败了一个人所以最低排名第7;


#include<cstring>#include<iostream>#include<cstdio>#include<algorithm>#include<cmath>#include<vector>#include<queue>#include<map>#define mem(n,t) memset(n,t,sizeof(n))using namespace std;typedef long long ll;int a[500],b[500],c[500],d[500],vis[500],ans[500];int main(){int k,n,m,T=1;while(scanf("%d",&n)&&n){if(T!=1)cout<<endl;T++;k=1;memset(ans,0,sizeof(ans));memset(b,0,sizeof(b));for(int i=1;i<=pow(2,n);i++){vis[i]=i;//i被vis[i]打败c[i]=i;d[i]=pow(2,n);}m=n;while(m){//ans数组计算每个数字出现的次数
//d数组计算每个人最低排名for(int i=1;i<=pow(2,m-1);i++){scanf("%d",&a[k++]);ans[a[k-1]]++;vis[c[i*2-1]]=vis[c[i*2]]=a[k-1];c[i]=a[k-1];d[c[i]]=pow(2,n)-pow(2,n-m+1)+1;//cout<<"i="<<i<<"  a[k-1]="<<a[k-1]<<"  c[i]="<<c[i]<<"  vis[c[i*2-1]]="<<vis[c[i*2-1]]<<"  vis[c[i*2]]="<<vis[c[i*2]]<<endl;}//cout<<endl;m--;}//for(int i=1;i<=k;i++)//printf("%d ",vis[i]);//cout<<endl;//for(int i=1;i<=k;i++)//cout<<ans[i]<<" ";//cout<<endl;for(int i=0;i<pow(2,n);i++){//b数组从最强开始计算每个人最高排名是多少for(int j=1;j<=pow(2,n);j++){if(ans[j]==n-i){b[j]=b[vis[j]]+1;}}}//for(int i=1;i<=pow(2,n);i++){//cout<<b[i]<<" ";//cout<<d[i]<<" "<<endl;//}int t;scanf("%d",&n);for(int i=0;i<n;i++){scanf("%d",&t);printf("Player %d can be ranked as high as %d or as low as %d.\n",t,b[t],d[t]);}}return 0;}