题解
题目要表达的意思特别绕,没看翻译之前,一度怀疑自己的水平?首先给你一个随机比赛序列。然后每NG个数的人在一个小组比赛。这个小组最肥的老鼠参加下一场比赛,在这一轮(所有的小组赛比完)淘汰的赋予排名,胜利的进入下一场比赛,重复上面的操作,一直找出冠军。
注意:到最后不足NG人也被视为一组
就拿题目中的数据来说:
6 0 8 一组 7 10 5 一组 9 1 4 一组 2 3 一组
4组最多诞生4个强人。所以所有淘汰的人排名是 5;
然后
8 7 9 3 作为优胜者参加下一场比赛
8 7 9 一组 3 一组
诞生2个强人。所有淘汰的人排名是 3;
8 3 一组
诞生1个强人(就是冠军)。所有淘汰的人排名是 1;
8
思路
1.向量数组weight,order,rank分别存老鼠重量、比赛顺序和排名,其中order数组动态存储当前比赛的人,即每次小组赛后删除败者
2.分组找出小组冠军,其他败者重量标记为-1,并赋值对应id的排名
3.赛后删除重量标记为-1的id
4.剩下的就是一些细节了,写的时候经常运行debug一下,不然整个程序写好后找bug真的很累
#include<iostream>
#include<vector>
using namespace std;
int main()
{
int np,ng;
cin>>np>>ng;
vector<int> weight(1005),rank(1005,-1);
vector<int> order(np);
for(int i=0;i<np;i++)
{
cin>>weight[i];//第i只老鼠的重量
}
for(int i=0;i<np;i++)
{
cin>>order[i];//比较顺序
}
int cur=np,currank;//cur当前人数,currank当前排名
while(cur>1)//下一场比赛的人数
{
currank=cur/ng+1;//当前败者排名
if(cur%ng)currank++;//最后一组虽然人数不足,
//但是还存在
for(int i=0;i<order.size();i+=ng)//一场比赛中组数
{
int maxwe=-1;
int pre=-1;//标记上一个最大值
for(int j=i;j<order.size()&&j<i+ng;j++)
{
if(weight[order[j]]>maxwe)//更新最大值
{
if(pre!=-1)//上一个最大值删除
{
weight[order[pre]]=-1;
rank[order[pre]]=currank;
}
maxwe=weight[order[j]];
pre=j;
}
else
{
weight[order[j]]=-1;
rank[order[j]]=currank;
}
}
}
for(int j=0;j<order.size();)
{
if(weight[order[j]]==-1)
{
order.erase(order.begin()+j);
}
else j++;
}
if(cur%ng) cur=cur/ng+1;
else cur=cur/ng;
}
for(int i=0;i<np;i++)
{
if(i!=0)
{
cout<<" ";
cout<<(rank[i]==-1?1:rank[i]);
}
else cout<<(rank[i]==-1?1:rank[i]);
}
return 0;
}