# 【深基16.例1】淘汰赛
## 题目描述
有 $2^n(n\le7)$ 个国家参加世界杯决赛圈且进入淘汰赛环节。已经知道各个国家的能力值,且都不相等。能力值高的国家和能力值低的国家踢比赛时高者获胜。1 号国家和 2 号国家踢一场比赛,胜者晋级。3 号国家和 4 号国家也踢一场,胜者晋级……晋级后的国家用相同的方法继续完成赛程,直到决出冠军。给出各个国家的能力值,请问亚军是哪个国家?
## 输入格式
第一行一个整数 $n$,表示一共 $2^n$ 个国家参赛。
第二行 $2^n$ 个整数,第 $i$ 个整数表示编号为 $i$ 的国家的能力值($1\leq i \leq 2^n$)。
数据保证不存在平局。
## 输出格式
仅一个整数,表示亚军国家的编号。
## 样例 #1
### 样例输入 #1
```
3
4 2 3 1 10 5 9 7
```
### 样例输出 #1
```
1
```
#include<stdio.h>
#include<algorithm>
#include<string.h>
#include<vector>
#include<iostream>
#include<math.h>
using namespace std;
int main()
{
int n;
cin >> n;
int k = pow(2, n);
vector<int>v1;
//录入数据
for (int i = 0; i < k; i++)
{
int temp;
cin >> temp;
v1.push_back(temp);
}
int F = 0, B = 1;
//循环n-1次
for (int i = 0; i < n-1; i++)
{
F = 0, B = 1;
//每次做k/2次比较
for (int j = 0; j < k / 2; j++)
{
//找到需要比较的两个数
while (v1.at(F) == 0)
{
F++;
}
B = F + 1;
while (v1.at(B) == 0)
{
B++;
}
//判断哪个数大,小的数赋值为0
if (v1.at(F) > v1.at(B))
{
v1.at(B) = 0;
F = B + 1;
B = B + 1;
}
else
{
v1.at(F) = 0;
F = B + 1;
B = B + 1;
}
}
k /= 2;
}
//最后剩下两个数没有比较,从中找到较小的那个数并输出下标+1
F = 0, B = 1;
while (v1.at(F) == 0)
{
F++;
}
B = F + 1;
while (v1.at(B) == 0)
{
B++;
}
if (v1.at(F) > v1.at(B))
{
cout << B + 1;
}
else
{
cout << F + 1;
}
}
然后贴一下大佬的做法,感觉比我的好
#include<iostream>
#include<queue>
#include<map>
using namespace std;
int main(){
int n;
queue<pair<int,int> > q; //pair是stl中的数据结构,这里用first表示国家号,second表示国家实力
cin>>n;
n=1<<n; //位运算,等价与n=pow(2,n)(位运算更快)
for(int i=1;i<=n;i++){
int x;
cin>>x;
q.push(make_pair(i,x)); //make_pair(i,x)就是建立一个first为i,second为x的pair
}
while(q.size()>2){ //循环将比赛进行至只剩前两名(q.size()为2是时要跳出循环单独判断亚军)
pair<int,int> x,y;
x=q.front();
q.pop();
y=q.front();
q.pop();
if(x.second>y.second){ //从队头取出两个队,进行比较后将较强的队压入队尾
q.push(x);
}else{
q.push(y);
}
}
pair<int,int> x,y;
x=q.front();
q.pop();
y=q.front();
q.pop();
if(x.second>y.second){ //较弱的那队时亚军,将其国家号输出
cout<<y.first<<endl;
}else{
cout<<x.first<<endl;
}
return 0;
}