*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,運行結果

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