1056 Mice and Rice (25 分)
题意
给出NP只老鼠的质量,并给出它们的初始顺序,按这个初始顺序把这些老鼠按每NG只分为一组,最后不够NG只的也单独分为一组。对每组老鼠,选出它们中质量最大的1只晋级,这样晋级的老鼠数就等于该轮分组的组数。对这些晋级的老鼠再按上面的步骤每NG只分为一组进行比较,选出质量最大的一批继续晋级,这样直到最后只剩下1只老鼠,排名为1。把这些老鼠的排名按原输入的顺序输出。
思路
- 开一个结构体mouse,用以记录每只老鼠的质量和排名。定义一个队列,用来在算法过程中按顺序处理每轮的老鼠。
- 算出以下几个数据。
- 每轮比赛把老鼠分成的组数group,设当前轮的参赛老鼠数有tot只,如果tot%NG为0,那么说明能够把老鼠完整划分,因此group=temp/NG;否则,说明最后会有少于NG只老鼠会单独分为一组,此时组数group=temp/NG+1。
- 由于每组晋级1只老鼠,因此当前轮晋级的总老鼠数等于group,且该轮未晋级的老鼠的排名均为group+1。
- 用tot记录当前轮的参赛老鼠数(初始为NP),group记录当前轮的组数,初始时把老鼠们的编号按顺序加入队列。之后进入while循环,每一层循环代表一轮比赛。
- 对每一轮比赛,枚举队列内的当前轮的tot只老鼠,按每NG只老鼠一组选出组内质量最大的老鼠,并将其入队表示晋级,而当前轮老鼠的排名(本轮比较分group个组,意味着有group个优胜者,也就是说,其余所有被淘汰的都在这group之后,即group+1)可在选出最大老鼠的过程中直接对每只老鼠都赋值(晋级的老鼠在下一轮比赛时会得到新的排名)。这样直到队列中只剩下1只老鼠,就把它的排名记为1。
- 最后输出所有老鼠的排名。
const int N=1010;
struct Node
{
int weight;
int rank;
}a[N];
int rank[N];
int n,k;
int main()
{
cin>>n>>k;
for(int i=0;i<n;i++) cin>>a[i].weight;
queue<int> q;
for(int i=0;i<n;i++)
{
int order;
cin>>order;
q.push(order);
}
while(q.size() > 1)
{
int tot=q.size();
int group=tot/k;
if(tot % k) group++;
for(int i=0;i<group;i++)
{
int index=-1;
for(int j=0;j<min(k,tot-i*k);j++)
{
int t=q.front();
q.pop();
if(index == -1 || a[t].weight > a[index].weight)
index=t;
a[t].rank=group+1;
}
q.push(index);
}
}
a[q.front()].rank=1;
for(int i=0;i<n;i++)
if(i) cout<<' '<<a[i].rank;
else cout<<a[i].rank;
cout<<endl;
//system("pause");
return 0;
}