熱門文章

2026年5月2日 星期六

ZeroJudge 解題筆記:d217. 00489 - Hangman Judge

作者:王一哲
日期:2026年5月2日


ZeroJudge 題目連結:d217. 00489 - Hangman Judge

解題想法


用字典 $state$ 記錄答案中每個字元是否被猜中,為了在檢查時比較好寫,我將還沒有被猜中的字元狀態標記成 True。再用另一個字典 $used$ 記錄已經猜過的字元。接下來依序讀取猜測字串的每個字元,檢查這個字元是否是答案、是否已經猜過,計算猜對的字元數量及猜錯的次數。最後依照猜對的字元數量及猜錯的次數輸出對應的答案。

Python 程式碼


使用時間約為 16 ms,記憶體約為 8.6 MB,通過測試。
def solve():
    import sys

    result = []  # 輸出的內容
    data = sys.stdin.read().split()
    ptr = 0
    while ptr < len(data):
        n = int(data[ptr])  # 編號
        ptr += 1
        if n == -1: break  # 中止迴圈
        result.append(f"Round {n:d}\n")
        ans = data[ptr]  # 答案
        ptr += 1
        state = {c: True for c in ans}  # 答案中各字母狀態,True 為還沒有猜中
        guess = data[ptr]  # 猜測的字串
        ptr += 1
        m, cnt, fails = len(state), 0, 0  # 答案共有 m 個相異字母,猜中 cnt 個,猜錯 fails 次
        used = dict()  # 已經猜過的字母
        """ 檢查是否過關 """
        for c in guess:  # 依序由 guess 讀取字母 c
            if c not in state:  # 如果 c 不在 state 之中
                if c not in used:  # 如果 c 不在 used 之中
                    fails += 1  # 新的猜錯字母,fails 加 1
                    if fails == 7:  break  # 猜錯 7 次,失敗,中止迴圈
            elif state[c]:  # 如果 c 在 state 之中而且 c 還沒有被猜中
                state[c] = False  # 設定為 False
                cnt += 1  # 猜中數量加 1
                if cnt == m: break  # 全部猜中,過關,中止迴圈
            used[c] = True  # c 加入 used
        """ 判斷答案 """
        if fails == 7:  # 失敗
            result.append("You lose.\n")
        else:
            if cnt == m:  # 過關
                result.append("You win.\n")
            else:  # 中離
                result.append("You chickened out.\n")
    """ 輸出答案 """
    sys.stdout.write("".join(result))

if __name__ == "__main__":
    solve()


C++ 程式碼


使用時間約為 3 ms,記憶體約為 3.2 MB,通過測試。
#include <iostream>
#include <string>
#include <unordered_map>
using namespace std;

int main() {
    ios::sync_with_stdio(0); cin.tie(0);
    int n;  // 編號
    while(cin >> n && n != -1) {
        cout << "Round " << n << "\n";
        string ans;
        cin >> ans;
        unordered_map<char, bool> state;  // 答案中各字母狀態,True 為還沒有猜中
        for(char c : ans) state[c] = true;
        string guess;
        cin >> guess;  // 猜測的字串
        int m = (int)state.size(), cnt = 0, fails = 0;  // 答案共有 m 個相異字母,猜中 cnt 個,猜錯 fails 次
        unordered_map<char, bool> used;  // 已經猜過的字母
        /* 檢查是否過關 */
        for(char c : guess) {  // 依序由 guess 讀取字母 c
            if (state.count(c) == 0) {  // 如果 c 不在 state 之中
                if (used.count(c) == 0) {  // 如果 c 不在 used 之中
                    fails++;  // 新的猜錯字母,fails 加 1
                    if (fails == 7)  break;  // 猜錯 7 次,失敗,中止迴圈
                }
            } else if (state[c]) {  // 如果 c 在 state 之中而且 c 還沒有被猜中
                state[c] = false;  // 設定為 False
                cnt++;  // 猜中數量加 1
                if (cnt == m) break;  // 全部猜中,過關,中止迴圈
            }
            used[c] = true;  // c 加入 used
        }
        /* 判斷答案 */
        if (fails == 7) {  // 失敗
            cout << "You lose.\n";
        } else {
            if (cnt == m) {  // 過關
                cout << "You win.\n";
            } else {  // 中離
                cout << "You chickened out.\n";
            }
        }
    }
    return 0;
}


沒有留言:

張貼留言