開啟章節選單

10903 Rock-Paper-Scissors Tournament

題目連結

提醒

此題名稱於官網標註為「Playing War」,經團隊研判可能為誤植,此頁面題解為經過團隊修正之內容。

題目敘述

兩位玩家玩剪刀石頭布遊戲:

  • 剪刀贏布

  • 布贏石頭

  • 石頭贏剪刀

出相同手勢為平手(不算勝也不算負)

現在有 n 位玩家,每對玩家要玩 k 次比賽。你的任務是計算每位玩家的「勝率」,公式如下: win / (win + lose) 平手不算進去,若某玩家完全沒有勝場或敗場(即沒參與非平手比賽 win + lose = 0),則輸出 -。

輸入格式

多組測資,第一行 n, k 接下來 k _ n _ (n - 1) / 2 行,每行分別為兩個玩家與玩家手勢。

輸出格式

對於每組測資,輸出 n 行,每行一位玩家的勝率(小數點後三位),或 - (若勝率無法計算)。

每組測資間 輸出一個空白行,但最後一組不可以多輸出空白行。

解題思路

模擬比賽:

  • 為每位玩家紀錄勝場與敗場。

  • 遇到平手不計入任何人戰績。

用函式決定勝負:

  • 比較兩個手勢,回傳誰贏誰輸(可用 pair<int, int>)

勝率計算與輸出:

  • 若 (win + lose) == 0 則輸出 -

  • 否則輸出 win / (win + lose),格式化輸出到小數點後三位

格式處理:

  • 每組測資間空一行,最後一組不多空行

程式碼

#include <bits/stdc++.h>
using namespace std;

pair<int, int> who_win(string a, string b, int pa, int pb) {
    if (a == b) return {0, 0};
    if ((a == "rock" && b == "scissors") ||
        (a == "scissors" && b == "paper") ||
        (a == "paper" && b == "rock")) {
        return {pa, pb};
    } else {
        return {pb, pa};
    }
}

int main() {
    int n, k;
    bool first_case = true;

    while (cin >> n >> k && n) {
        if (!first_case) cout << "\n";
        first_case = false;

        int win[101] = {0}, lose[101] = {0};
        string m1, m2;
        int p1, p2;
        int total_games = k * n * (n - 1) / 2;

        for (int i = 0; i < total_games; ++i) {
            cin >> p1 >> m1 >> p2 >> m2;
            auto result = who_win(m1, m2, p1, p2);
            if (result.first != 0) {
                win[result.first]++;
                lose[result.second]++;
            }
        }

        for (int i = 1; i <= n; i++) {
            if (win[i] + lose[i] == 0) {
                cout << "-\n";
            } else {
                double rate = (double)win[i] / (win[i] + lose[i]);
                cout << fixed << setprecision(3) << rate << "\n";
            }
        }
    }

    return 0;
}