题目
思路
题意是给你每个老鼠的重量,请你根据老鼠的重量为他们排名;
但排名并不是通过一场比赛决定,而是通过小组赛的方式,意味着重的老鼠不一定排名靠前;
小组赛机制是每轮将剩余选手分成小组,每个小组选一名选手晋级下一轮;
首先来思考如何得到每个选手的排名,因为每轮失败的选手排名一样,所以每轮晋级的选手数 + 1 就是本轮失败选手的排名;
我们可以用队列进行模拟,队列中存放的是选手的ID,在开始每一轮比赛前,先获取队列中元素的个数,也就是本轮参赛选手的人数,然后将本轮参赛选手依次出队,出队的过程中为那些淘汰的人写入排名,那些晋级的人排名未知,需要在下一轮才能得到;
注意到每个小组胜利的人需要再次入队,进行下一轮比赛;
代码
#include <iostream>
#include <vector>
#include <stack>
#include <queue>
using namespace std;
const int maxn = 1010;
int NP, NG, temp;
vector<int> w(maxn), rankk(maxn);
queue<int> qu;
int main()
{
//读入组数
scanf("%d%d", &NP, &NG);
for(int i = 0; i < NP; i ++) scanf("%d", &w[i]);
//把每一个人都放进队列中
for(int i = 0; i < NP; i ++) {
scanf("%d", &temp);
qu.push(temp);
}
int pre = -1, cur;//pre代表每个小组晋级人的下标
while(qu.size() > 1){
int cnt = qu.size();//cnt代表这轮一共有多少人
int r = 0;
//r代表这局淘汰的人的排名,如果可以整除,就代表有cnt / NG 个小组,不可以整除就代表有cnt / NG + 1个小组
if(cnt % NG == 0) r = cnt / NG + 1;
else r = cnt / NG + 2;
//将这cnt个人出队
for(int i = 1; i <= cnt; i ++){
cur = qu.front();
qu.pop();
//pre == -1代表这个人是小组的第一人,自然不需要比较
if(pre == -1) pre = cur;
//如果当前选手的重量大于小组目前重量最大值,更新pre
else if(w[cur] > w[pre]){
rankk[pre] = r;
pre = cur;
}
else if(w[cur] < w[pre]){
rankk[cur] = r;
}
//当每个小组比赛结束后,需要将胜利人的ID放入队列,进行下一轮比赛
if(i % NG == 0 || i == cnt){
qu.push(pre);
if(qu.size() != 1) pre = -1;
}
}
}
rankk[pre] = 1;
for(int i = 0; i < NP; i ++){
printf("%d", rankk[i]);
if(i != NP - 1) printf(" ");
}
//system("pause");
return 0;
}
吐槽:这道题想了好长时间啊,WA