目录
1,题目描述
题目大意
输入
输出
2,思路
数据结构
算法
3,代码
4,运行结果
1,题目描述
(这一题是真的迷,看了N遍,硬生生没看懂什么意思。。。)
Sample Input:
11 3
25 18 0 46 37 3 19 22 57 56 10
6 0 8 7 10 5 9 1 4 2 3
Sample Output:
5 5 5 2 5 5 5 3 1 3 5
题目大意
(按照体重和运气给所有的mice排名。也就是说排名靠前的,不一定是最重的,也可能是比赛那一组里的其他对手太弱。)
按0 - N-1的顺序给出每只老鼠的重量。然后给出每只老鼠的出场顺序,每Ng只老鼠分为一组,选出最重的。第一轮中的winner抽出来,进行第二轮……直到选出第一名。
按照编号顺序输出每只老鼠的排名。
(虽然很绕,但确实更接近生活中的例子)
输入
- 第一行:Np参赛人数,Ng每组的人数;
- 第二行:编号从0到Np-1的参赛选手的重量;
- 第三行:参赛人员的出场顺序;
输出
- 按编号输出每位参赛选手的排名;
2,思路
(这一题参考了柳神的做法。膜拜!!!)
数据结构
- struct node{int weight, id, order, rank;}:weight重量 ,id编号, order出场顺序, rank排名;
- vector<node> data(Np):存放所有参赛选手的信息(包括编号和出场顺序);
- queue<node> q:用队列模拟比赛流程,按照出场顺序存放选手的信息,并在每个选手出队时,填充排名字段;
算法
- 将所有的选手信息按照出场顺序入队;
- 每出队一名选手(淘汰),该选手的排名便已经确定(为group+1,比如,当前轮次有四组,则每一组选出一名优胜者,一共四名,按照非递增排序,这一轮淘汰的选手排名均为4+1);
- 选出的优胜者重新进入队列的尾部,继续进行下一轮的筛选;
- 当队列中只有一名选手时,他就是冠军!结束队列的循环;
- 再将选手按照编号重新排序,输出每个选手的排名;
3,代码
#include<iostream>
#include<algorithm>
#include<vector>
#include<queue>
using namespace std;
int flag;
struct node{
int weight, id, order, rank; //weight重量 id编号 order顺序 rank排名
};
bool cmp1(node a, node b){
if(flag == 1)
return a.order < b.order;
else if(flag == 2)
return a.id < b.id;
}
int main(){
#ifdef ONLINE_JUDGE
#else
freopen("1.txt", "r", stdin);
#endif // ONLINE_JUDGE
int Np, Ng; //Np参赛老鼠数目 Ng每组包含老鼠数目
cin>>Np>>Ng;
vector<node> data(Np); //按编号顺序存放每只老鼠的体重
queue<node> q;
int w;
for(int i = 0; i < Np; i++){
scanf("%d", &w);
data[i].weight = w;
data[i].id = i;
}
for(int i = 0; i < Np; i++){
scanf("%d", &w);
data[w].order = i;
}
flag = 1;
sort(data.begin(), data.end(), cmp1); //按照出场顺序排序
for(int i = 0; i < Np; i++)
q.push(data[i]);
while(!q.empty()){ //每出队一个元素 可以确定他的排名
int curNum = q.size(); //curNum为这一轮的参赛队员人数
if(q.size() == 1){ //冠军诞生
data[q.front().order].rank = 1;
break;
}
int group = q.size() / Ng; //求出当前的队员数目可以组成的队伍数
if(q.size() % Ng != 0) group++;
for(int g = 0; g < group; g++){ //每组选出冠军 重新进入队列尾部
node maxNode, temp;
maxNode.weight = -1;
for(int i = 0; i < Ng && curNum > 0; i++){
temp = q.front();
data[temp.order].rank = group + 1; //group+1即为此轮淘汰的选手的名次
q.pop();
curNum--;
if(temp.weight > maxNode.weight)
maxNode = temp;
}
q.push(maxNode);
maxNode.weight = -1;
}
}
flag = 2;
sort(data.begin(), data.end(), cmp1); //按照编号重新排序
printf("%d", data[0].rank);
for(int i = 1; i < Np; i++)
printf(" %d", data[i].rank);
}