L2-047 锦标赛
有 2
k
名选手将要参加一场锦标赛。锦标赛共有 k 轮,其中第 i 轮的比赛共有 2
k−i
场,每场比赛恰有两名选手参加并从中产生一名胜者。每场比赛的安排如下:
对于第 1 轮的第 j 场比赛,由第 (2j−1) 名选手对抗第 2j 名选手。
对于第 i 轮的第 j 场比赛(i>1),由第 (i−1) 轮第 (2j−1) 场比赛的胜者对抗第 (i−1) 轮第 2j 场比赛的胜者。
第 k 轮唯一一场比赛的胜者就是整个锦标赛的最终胜者。
举个例子,假如共有 8 名选手参加锦标赛,则比赛的安排如下:
第 1 轮共 4 场比赛:选手 1 vs 选手 2,选手 3 vs 选手 4,选手 5 vs 选手 6,选手 7 vs 选手 8。
第 2 轮共 2 场比赛:第 1 轮第 1 场的胜者 vs 第 1 轮第 2 场的胜者,第 1 轮第 3 场的胜者 vs 第 1 轮第 4 场的胜者。
第 3 轮共 1 场比赛:第 2 轮第 1 场的胜者 vs 第 2 轮第 2 场的胜者。
已知每一名选手都有一个能力值,其中第 i 名选手的能力值为 a
i
。在一场比赛中,若两名选手的能力值不同,则能力值较大的选手一定会打败能力值较小的选手;若两名选手的能力值相同,则两名选手都有可能成为胜者。
令 l
i,j
表示第 i 轮第 j 场比赛 败者 的能力值,令 w 表示整个锦标赛最终胜者的能力值。给定所有满足 1≤i≤k 且 1≤j≤2
k−i
的 l
i,j
以及 w,请还原出 a
1
,a
2
,⋯,a
n
。
输入格式:
第一行输入一个整数 k(1≤k≤18)表示锦标赛的轮数。
对于接下来 k 行,第 i 行输入 2
k−i
个整数 l
i,1
,l
i,2
,⋯,l
i,2
k−i
(1≤l
i,j
≤10
9
),其中 l
i,j
表示第 i 轮第 j 场比赛 败者 的能力值。
接下来一行输入一个整数 w(1≤w≤10
9
)表示锦标赛最终胜者的能力值。
输出格式:
输出一行 n 个由单个空格分隔的整数 a
1
,a
2
,⋯,a
n
,其中 a
i
表示第 i 名选手的能力值。如果有多种合法答案,请输出任意一种。如果无法还原出能够满足输入数据的答案,输出一行 No Solution。
请勿在行末输出多余空格。
输入样例1:
3
4 5 8 5
7 6
8
9
输出样例1:
7 4 8 5 9 8 6 5
输入样例2:
2
5 8
3
9
输出样例2:
No Solution
提示:
本题返回结果若为格式错误均可视为答案错误。
代码
include<bits/stdc++.h>
using namespace std;
const int N=1<<19;
struct Node{
int w,l;
}node[N];
bool dfs(int u,int size)
{
if(u>size)return 1;
if(node[u].l>node[u].w)return 0;
node[2u].w=node[u].w;
node[2u+1].w=node[u].l;
if(dfs(2u,size)&&dfs(2u+1,size))return 1;
swap(node[2u].w,node[2u+1].w);
if(dfs(2u,size)&&dfs(2u+1,size))return 1;
return 0;
}
signed main()
{ ios::sync_with_stdio(0);
cin.tie(0),cout.tie(0);
int k;
if(!(cin>>k))return 0;
for(int i=k-1;i>=0;i--)
{
int st=1<<i;
int ed=1<<(i+1);
for(int j=st;j<ed;j++)
{
cin>>node[j].l;
}
}
cin>>node[1].w;
int treesize=(1<<k)-1;
if(dfs(1,treesize))
{
int st=1<<(k-1);
int ed=1<<k;
for(int i=st;i<ed;i++)
{
cout<<node[i].w<<" "<<node[i].l;
if(i!=ed-1)cout<<" ";
}
}else{
cout<<"No Solution"<<endl;
}
return 0;
}
思路
将输赢流程图看作一棵树,每一次比赛看作一个节点Node,头节点存最后一次比赛的输赢
层层递归,如果合法即可得到一组答案,因为头节点的赢家和败者都是上一场(即下一层树的节点)的赢家
node[2u].w=node[u].w;
node[2u+1].w=node[u].l;通过 if(dfs(2u,size)&&dfs(2u+1,size))return 1;递归
并且尝试swap(node[2u].w,node[2u+1].w);每种答案,找寻一组正确答案。

浙公网安备 33010602011771号