PAT甲級1056Mice and Rice

題目介紹

  • 題目鏈接

    //pintia.cn/problem-sets/994805342720868352/problems/994805419468242944

  • 題目考點

    隊列、模擬。重點在模擬,隊列只用到了建立、入隊、出隊、清空(需要自己實現,創建新的隊列然後賦值或者swap)。

  • 題目難度

    PAT甲級25分

  • 題目大意

    • 給定1個圖,每個玩家控制1隻老鼠移動,每個老鼠的目標是儘可能多地吃大米變成Fat Mouse。
    • \(N_P\)個玩家的順序是隨機的,每\(N_G\)個玩家分成1組進行比賽。每輪的獲勝者繼續每\(N_G\)個玩家分成一組進行比賽,直到最後1隻老鼠。
    • 每組中最快的老鼠獲勝並進入下一輪,一輪中失敗的老鼠的rank(排名)相同。
    • 假設每隻老鼠的重量是固定的,給出所有大米的重量和玩家初始順序,請輸出每個玩家的rank。
  • 輸入

    • \(N_P\):玩家的數量,正整數,不超過1000
    • \(N_G\):每組中最多有幾個玩家(如果剩下的老鼠不夠\(N_G\)只,這幾隻就形成最後一組),正整數,不超過1000
    • \(W_i\)\(N_P\)個老鼠的重量,互異的非負數
    • \(N_P\)個玩家的順序,玩家索引為\([0,N_P-1]\)
  • 輸出

    • 按玩家索引順序最終所有玩家的rank

題解

解題思路

  • 兩個隊列:一個保存本輪玩家,一個保存下輪玩家,一直循環到結束(隊列里只有1個人)。

  • 關於rank,起初我的想法是通過比賽輪數得到rank,然而發現不行,因為rank要看人數,而不是由在幾輪失敗決定。

    怎麼算rank我也想了挺久,後來看了題解才知道:5個人比賽,2個人晉級,那這失敗的3個人的rank就是3(即2+1)妙啊。

  • 除了rank,其它部分就比較簡單了。

程式碼

// Problem: PAT Advanced 1056
// URL: //pintia.cn/problem-sets/994805342720868352/problems/994805419468242944
// Tags: 

#include <iostream>
#include <queue>
using namespace std;

int playerNum, playerMaxNumInAGroup; // 玩家數量,1組最多多少玩家
queue<int> nowPlayers, nextPlayers;     // 本輪玩家的索引和下輪玩家的索引
int weight[1002]; // 老鼠的重量
int rrank[1002]; // 玩家的排名
int groupNum; // 本輪比賽有多少組


/*一組玩家進行比賽*/
int findFatMouse(){
    int maxWeight = weight[nowPlayers.front()], fatMouse = nowPlayers.front();
    rrank[nowPlayers.front()] = groupNum + 1;
    nowPlayers.pop();

    for (int i=1; i < playerMaxNumInAGroup && !nowPlayers.empty(); i++){
        if (weight[nowPlayers.front()] > maxWeight){
            maxWeight = weight[nowPlayers.front()];
            fatMouse = nowPlayers.front();
        }
        rrank[nowPlayers.front()] = groupNum + 1;
        nowPlayers.pop();
    }
    nextPlayers.push(fatMouse);
}

/*計算本輪比賽有幾組*/
int calcGroupNum(){
    int nowPlayerNum = nowPlayers.size();
    if (nowPlayerNum % playerMaxNumInAGroup == 0)
        return nowPlayerNum / playerMaxNumInAGroup;
    else
        return nowPlayerNum / playerMaxNumInAGroup + 1;
}

int main()
{
    // 讀取變數
    scanf("%d%d", &playerNum, &playerMaxNumInAGroup);
    for(int i=0; i < playerNum; i++)
        scanf("%d", weight+i);
    for(int i=0, player; i < playerNum; i++){
        scanf("%d", &player);
        nowPlayers.push(player);
    }

    // 進行比賽
    while(nowPlayers.size() > 1){
        nextPlayers = queue<int>(); // 清空下一輪比賽的玩家隊列
        groupNum = calcGroupNum();  // 計算本輪比賽有幾組,本輪失敗的玩家的rank即為groupNum + 1
        for (int i = 0; i < groupNum; i++) // 進行本輪的groupNum組比賽
            findFatMouse(); // 一組玩家進行比賽
        nowPlayers = nextPlayers; // 進行下一輪比賽,更新玩家隊列
    }
    rrank[nowPlayers.front()] = 1; // 剩下的1個人就是最終的第1名

    // 輸出排名
    printf("%d", rrank[0]);
    for (int i = 1; i < playerNum; i++)
        printf(" %d", rrank[i]);
    return 0;
}

參考鏈接


Github(github.com):@chouxianyu

Github Pages(github.io):@臭鹹魚

知乎(zhihu.com):@臭鹹魚

部落格園(cnblogs.com):@臭鹹魚

B站(bilibili.com):@絕版臭鹹魚

微信公眾號:@臭鹹魚的快樂生活

轉載請註明出處,歡迎討論和交流!