1056 Mice and Rice (25 分)

题意

给出NP只老鼠的质量,并给出它们的初始顺序,按这个初始顺序把这些老鼠按每NG只分为一组,最后不够NG只的也单独分为一组。对每组老鼠,选出它们中质量最大的1只晋级,这样晋级的老鼠数就等于该轮分组的组数。对这些晋级的老鼠再按上面的步骤每NG只分为一组进行比较,选出质量最大的一批继续晋级,这样直到最后只剩下1只老鼠,排名为1。把这些老鼠的排名按原输入的顺序输出。

思路

  1. 开一个结构体mouse,用以记录每只老鼠的质量和排名。定义一个队列,用来在算法过程中按顺序处理每轮的老鼠。
  2. 算出以下几个数据。
    • 每轮比赛把老鼠分成的组数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;
}
原文地址:https://www.cnblogs.com/fxh0707/p/14431846.html