UVa 489 Hangman Judge

题目描述

题目要求模拟刽子手游戏,并根据给定规则判断每轮游戏的结果。游戏规则如下:

  • 每轮游戏给出一个单词(答案)和一系列猜测字母。
  • 每次猜测一个字母,若该字母在单词中,则单词中所有该字母被“翻开”;若不在,则增加一笔画(共需 777 笔完成)。
  • 每个错误字母只计一次(重复错误不计)。
  • 若在画完 777 笔之前猜出所有字母,则玩家获胜。
  • 若画完 777 笔仍未猜出所有字母,则玩家失败。
  • 若猜测序列结束后仍未获胜也未失败,则玩家放弃。

输入格式

输入包含多轮游戏,每轮三行:第一行一个整数表示轮次编号(−1-11 表示输入结束),第二行是答案单词,第三行是猜测字母序列(可能包含重复字母)。所有字母均为小写。

输出格式

对于每轮游戏,输出一行:

Round X
结果

其中 X 为轮次编号,结果为 You win.You lose.You chickened out.

样例

输入

1
cheese
cheese
2
cheese
abcdefg
3
cheese
abcdefgij
-1

输出

Round 1
You win.
Round 2
You chickened out.
Round 3
You lose.

题目分析

本题的核心是模拟刽子手游戏的过程,并判断最终结果。

数据结构

  • 使用集合 all\textit{all}all 存储答案单词中的所有不同字母。
  • 使用集合 right\textit{right}right 存储已猜对的字母。
  • 使用集合 wrong\textit{wrong}wrong 存储已猜错的字母(去重)。

模拟过程

遍历猜测序列中的每个字母 ggg

  1. ggg 已经猜过(在 right\textit{right}rightwrong\textit{wrong}wrong 中),则跳过(重复猜测不影响)。
  2. gggall\textit{all}all 中(正确猜测):
    • ggg 加入 right\textit{right}right
    • all\textit{all}all 中删除 ggg
    • all\textit{all}all 为空,则玩家获胜,结束。
  3. ggg 不在 all\textit{all}all 中(错误猜测):
    • ggg 加入 wrong\textit{wrong}wrong
    • wrong\textit{wrong}wrong 的大小达到 777,则玩家失败,结束。
  4. 若遍历完所有猜测后仍未获胜或失败,则玩家放弃。

复杂度分析

每轮游戏处理 O(猜测长度+答案长度)O(\text{猜测长度} + \text{答案长度})O(猜测长度+答案长度),完全可接受。

代码实现

// Hangman Judge
// UVa ID: 489
// Verdict: Accepted
// Submission Date: 2016-07-14
// UVa Run Time: 0.580s
//
// 版权所有(C)2016,邱秋。metaphysis # yeah dot net

#include <bits/stdc++.h>

using namespace std;

int main(int argc, char *argv[])
{
    ios::sync_with_stdio(false);

    int round;
    string solution, guess;
    while (cin >> round, round != -1)
    {
        cout << "Round " << round << endl;
        cin >> solution >> guess;
        
        bool flag = false;
        set<char> right, wrong, all;
        for (int i = 0; i < solution.length(); i++)
            all.insert(solution[i]);
        
        for (int i = 0; i < guess.length(); i++)
        {
            if (right.find(guess[i]) != right.end()) continue;
            
            if (all.find(guess[i]) == all.end())
            {
                wrong.insert(guess[i]);
                if (wrong.size() >= 7)
                {
                    cout << "You lose." << endl;
                    flag = true;
                    break;
                }
            }
            else
            {
                right.insert(guess[i]);
                all.erase(guess[i]);
                if (all.size() == 0)
                {
                    cout << "You win." << endl;
                    flag = true;
                    break;
                }
            }
        }
        
        if (!flag) cout << "You chickened out." << endl;
    }
    
    return 0;
}
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值