题目描述
总共Np个人,每个人有一个权重,以Ng个人为一个小组,分组进行评比。每次选出每组权重最大的那一个人进入下一轮,其他人就停在这一轮,且排名相同。每轮都分组评选,直到评出第一名。
最后要求输出每个人的排名rank
题目
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
思路
难点〇:理解题意
多读几遍,在纸上画一下,其实就像淘汰赛
难点一:队列表示每一轮
本来没有想到用队列来存储每一轮的参赛者们。
因为小组的顺序是依次下来的,因此还是用队列最为方便。
难点二:计算每个人最后的rank
每一轮失败者的rank = 本轮分出的小组数 + 1。
因为每一个小组中都有一个胜者,所以总共有小组数个胜者排在前面,那么又因为失败者的名次都相同,所以他们都是小组数+1。
流程图
AC代码
#include<bits/stdc++.h>
using namespace std;
int main(){
int n,g;
cin>>n>>g; //总人数,每组人数
int w[n]; //权重
int r[n]; //排名
for(int i=0;i<n;++i)
cin>>w[i];
queue<int> q,p;
for(int i = 0;i<n;++i){
int indx;
cin>>indx;
q.push(indx);
}
while(1){
int ngrp = q.size()%g==0?q.size()/g : q.size()/g+1;//组数
while(!q.empty()){
int maxI = -1;
int maxW = -1;
for(int i = 0;i<g;++i){
if(!q.empty()){
int member = q.front();q.pop();
r[member] = ngrp+1; //排名为组数加1
if(w[member]>maxW){
maxW = w[member];
maxI = member;
}
}
}
p.push(maxI); //每组胜者进入下一轮
}
if(p.size()!=1){//用p更新q,将p置空为下一轮做准备
q = p;
queue<int> emptyQ;
swap(p,emptyQ);
}else{
r[p.front()] = 1;
break;
}
}
//输出结果
printf("%d",r[0]);
for(int i = 1;i<n;++i){
printf(" %d",r[i]);
}
return 0;
}