*PAT_甲级_1056 Mice and Rice (25分) (C++)【模拟/队列的应用】

目录

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的参赛选手的重量;
  • 第三行:参赛人员的出场顺序;

输出

  1. 按编号输出每位参赛选手的排名; 

 

2,思路

(这一题参考了柳神的做法。膜拜!!!)

数据结构

  • struct node{int weight, id, order, rank;}:weight重量 ,id编号, order出场顺序, rank排名;
  • vector<node> data(Np):存放所有参赛选手的信息(包括编号和出场顺序);
  • queue<node> q:用队列模拟比赛流程,按照出场顺序存放选手的信息,并在每个选手出队时,填充排名字段;

算法

  1.  将所有的选手信息按照出场顺序入队;
  2. 每出队一名选手(淘汰),该选手的排名便已经确定(为group+1,比如,当前轮次有四组,则每一组选出一名优胜者,一共四名,按照非递增排序,这一轮淘汰的选手排名均为4+1);
  3. 选出的优胜者重新进入队列的尾部,继续进行下一轮的筛选;
  4. 当队列中只有一名选手时,他就是冠军!结束队列的循环;
  5. 再将选手按照编号重新排序,输出每个选手的排名;

 

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);
}

4,运行结果

發表評論
所有評論
還沒有人評論,想成為第一個評論的人麼? 請在上方評論欄輸入並且點擊發布.
相關文章