思路
模拟比赛这个应该不难,书里面是用一个队列,不难发现比赛的过程有点类似树的层次遍历,但它是从下往上遍历;我是用优先队列整,毕竟他有着只关注优先级最高的特点,符合题意。令我稍有点头疼的是名次,刚开始我是先把所有人的名词都设成1,然后用一个vector存败者,每轮比赛过后吧这个vector里的人的名次都加1,这明显不符题意,就像注释里说的就算3个人并列第一,第四个人也是第四名而不是第二,那么接下来的问题就是类似于排名了,而我预先弄的排名就像是分数,相同分数意味着相同名次,得根据这些分数重新排下名,想了好久没想出好办法,如果有朋友有好方法希望能指点下俺,感激不尽。不过书里很聪明,每轮的晋级者的个数加一刚好是这轮败者的名次,厉害啊!
#include <cstdio>
#include <algorithm>
#include <vector>
#include <queue>
using namespace std;
struct programmer
{
int rank;
int weight;
}programmers[1010];
struct cmp {
bool operator () (int A, int B){
return programmers[A].weight < programmers[B].weight;
}
};
int main(){
//total num of programmers, num of programmers in one group
int NP, NG;
scanf("%d%d", &NP, &NG);
for(int i = 0; i < NP; i++){
scanf("%d", &programmers[i].weight);
programmers[i].rank = 1;
}
//loser用来存储失败者的序号,winner用来存每轮的参赛者的序号
vector<int> loser;
queue<int> winner;
for(int i = 0; i < NP; i++){
int order;
scanf("%d", &order);
winner.push(order);
}
//如果参赛者大于1说明还有比赛,则继续循环,每一次循环是一轮比赛
while(winner.size() > 1){
int cnt = winner.size();
//用优先队列来组织每一组比赛
priority_queue<int, vector<int>, cmp> q;
for(int i = 0; i < cnt; i++){
q.push(winner.front());
winner.pop();//参加了比赛就把他从参赛者中删除
//组满了或者最后一组人数不够
if(q.size() == NG || (q.size() > 0 && i == cnt - 1)){
//每一组最大者进入下一轮
winner.push(q.top());
q.pop();
//每一组的败者全部到loser里面去
while(!q.empty()){
loser.push_back(q.top());
q.pop();
}
}
}
//没过完一轮,把败者的名词加1,注意这里假如3人并列第一,第四个人不是第四名
//而是3人并列第一,第四人是第二名
for(int i = 0; i < loser.size(); i++)
programmers[loser[i]].rank++;
}
//重新修改名词,此时3人并列第一,第四人是第4名
loser.push_back(winner.front());//把第一名也放进来,方便统一修改
int max = programmers[loser[0]].rank;//表示要修改几轮
int cnt = 0, before = 0;//cnt记录已经修改了多少人的名次,before是前面这些人是第几名
//每次修改原名词为i的programmer
for(int i = 1; i <= max; i++){
while(cnt < loser.size() && programmers[loser[loser.size() - 1 - cnt]].rank == i){
programmers[loser[loser.size() - 1 - cnt]].rank = before + 1;
cnt++;
}
before = cnt;
}
//标准输出
for(int i = 0; i < NP; i++){
if(i == 0)
printf("%d", programmers[i].rank);
else
printf(" %d", programmers[i].rank);
}
printf("\n");
return 0;
}