Simons' Trials--Chapter 4 B

Uva 489 Hangman Judge

In “Hangman Judge,” you are to write a program that judges a series of Hangman games. For each
game, the answer to the puzzle is given as well as the guesses. Rules are the same as the classic game
of hangman, and are given as follows:
1. The contestant tries to solve to puzzle by guessing one letter at a time.
2. Every time a guess is correct, all the characters in the word that match the guess will be “turned
over.” For example, if your guess is ‘o’ and the word is “book”, then both ‘o’s in the solution will
be counted as “solved”.
3. Every time a wrong guess is made, a stroke will be added to the drawing of a hangman, which
needs 7 strokes to complete. Each unique wrong guess only counts against the contestant once.
| |
| O
| /|\
| |
| / \
_|
| |__
|___|
4. If the drawing of the hangman is completed before the contestant has successfully guessed all the
characters of the word, the contestant loses.
5. If the contestant has guessed all the characters of the word before the drawing is complete, the
contestant wins the game.
6. If the contestant does not guess enough letters to either win or lose, the contestant chickens out.
Your task as the “Hangman Judge” is to determine, for each game, whether the contestant wins,
loses, or fails to finish a game.
Input
Your program will be given a series of inputs regarding the status of a game. All input will be in lower
case. The first line of each section will contain a number to indicate which round of the game is being
played; the next line will be the solution to the puzzle; the last line is a sequence of the guesses made
by the contestant. A round number of ‘-1’ would indicate the end of all games (and input).
Output
The output of your program is to indicate which round of the game the contestant is currently playing
as well as the result of the game. There are three possible results:
You win.
You lose.
You chickened out.
Sample Input
1
cheese
chese
2
cheese
abcdefg
3
cheese
abcdefgij
-1
Sample Output
Round 1
You win.
Round 2
You chickened out.
Round 3
You lose.


 紫书上这一道是例题,刘神用来讲解了程序的写成顺序(自顶向下还是自底向上)及一些细节如变量名的选取(不与库重复),是选择用全局变量还是选择用指针传参等(刘神选了全局,并觉得用指针传参丑),最后点了点变量与调试。
 讲的自然是好哇,然而还是要做这道题又是另回事了,因为紫书的题干一向简明扼要,这次又被它的分析带了进去(还有自己的另外两个错误,真的是没严谨地做啊,掩泪)WA 和TLE了好久。这里记录下我与这题主要的纠葛。

  1. TLE的原因:说好了-1的时候就结束呢!!这是我最后才发现的……( A round number of ‘-1’ would indicate the end of all games (and input))…警示警示!
  2. 紫书有言:“题目中说了猜过的字母再猜一次算错。”然而题目中言:Each unique wrong guess only counts against the contestant once.???实践证明紫书写错了,表示真的要练英语基础,不然太伤感情了,枉费了我对紫书的一片信任啊(玩笑话,紫书也是书啊,敢于怀疑自强自信才是真理)~
  3. 题中并没有讲输入的两个串的长度,而紫书上的示例代码定义了串长maxn为100(书上会这样写肯定是能AC了),但对此我持保留态度。因为注意到一共只有26个字母,所以我用了计数法,且边输入边记录,而且这个方法比书上用的要好很多。附上最初TLE的代码,错误标记在代码里:
//scheme 1(attempted)
#include <stdio.h>
#include <string.h>

void printAns(int, int);
int main(void)
{
    char solution[26];
    char guess[26];
    char ch;
    int strokes;
    int round, ans;

    //error #1:what's the end of input?
    while (scanf("%d", &round) == 1)
    {
        //Initiation
        strokes = 0;
        ans = 2;
        memset(solution, 0, sizeof(solution));
        memset(guess, 0, sizeof(guess));

        //Input and processing
        getchar();
        while ((ch = getchar()) != '\n')
            solution[ch - 'a']++;
        while ((ch = getchar()) != '\n')
        {
            //Each unique wrong guess only counts against the contestant once
            if (!guess[ch - 'a'])
            {
                guess[ch - 'a']++;
                if (solution[ch - 'a'])
                    solution[ch - 'a'] = 0;
                else
                    strokes++;
            }
        }
        //error #2:how about the condition that the time of strokes has already 
        //been 7 before the puzzle is solved?(this shouldn't be counted but my code ignores it)
        //Judging all at one time
        int i;
        for (i = 0; i < 26; i++)
            if (solution[i])
                break;
        if (i == 26)
            ans = 0;
        else if (strokes >= 7)
            ans = 1;
        printAns(round, ans);
    }
    return 0;
}

void printAns(int r, int a)
{
    char ans[3][20] = {"You win.",
                     "You lose.",
                     "You chickened out."};
    printf("Round %d\n%s\n", r, ans[a]);
    return;
}
//Time Limit Exceeded

这个TLE一开始我以为是逐个的读取太慢了,于是用scanf(“%s”)配合指针来替代,结果变成了WA(应该是还没测完就出错了,但上面的代码改了error #1之后交上也从TLE变成了WA,这里我就糊了。。有谁知道为什么吗?恳请看到并知道的留个言谢谢大恩!),之后发现了error #2,改成了如下代码:

//scheme 2(attempted)
#include <stdio.h>
#include <string.h>

void printAns(int, int);
int main(void)
{
    int solution[26];
    int guess[26];
    char temp[112];
    int strokes;
    int round, ans;

    //error #1
    while (scanf("%d", &round) == 1)
    {
        //Initiation
        strokes = 0;
        ans = 2;
        memset(solution, 0, sizeof(solution));
        memset(guess, 0, sizeof(guess));

        //Input and processing
        scanf("%s", temp);
        char *p = temp;
        while (*(p++) != 0)//error #3 increase too early
            solution[*p - 'a']++;
        scanf("%s", temp);
        p = temp;
        while (*(p++) != 0)//error #3
        {
            //Each unique wrong guess only counts against the contestant once
            if (!guess[*p - 'a'])
            {
                guess[*p - 'a']++;
                if (solution[*p - 'a'])
                    solution[*p - 'a'] = 0;
                else
                    strokes++;
            }
            if (strokes >= 7)
                break;
        }

        //Judging all at one time
        int i;
        for (i = 0; i < 26; i++)
            if (solution[i])
                break;
        if (i == 26)
            ans = 0;
        else if (strokes >= 7)
            ans = 1;
        printAns(round, ans);
    }
    return 0;
}

void printAns(int r, int a)
{
    char ans[3][20] = {"You win.",
                     "You lose.",
                     "You chickened out."};
    printf("Round %d\n%s\n", r, ans[a]);
    return;
}//Wrong Answer

为我的愚感动到。。
不过,我依旧不知道为什么在上面的代码里把error #3 改正后提交结果就变成了WA而不是TLE,求大神指教啊~
下面是两个方式的AC代码,第二个是一个看了别人博客之后的改进版。

//scheme 1 Accepted
#include <stdio.h>
#include <string.h>

void printAns(int, int);
int main(void)
{
    char solution[26];
    char guess[26];
    char ch;
    int strokes;
    int round, ans;

    while (scanf("%d", &round) == 1 && round != -1)
    {
        //Initiation
        strokes = 0;
        ans = 2;
        memset(solution, 0, sizeof(solution));
        memset(guess, 0, sizeof(guess));

        //Input and processing
        getchar();
        while ((ch = getchar()) != '\n')
            solution[ch - 'a']++;
        while ((ch = getchar()) != '\n')
        {
            if (strokes >= 7)
                continue;
            //Each unique wrong guess only counts against the contestant once
            if (!guess[ch - 'a'])
            {
                guess[ch - 'a']++;
                if (solution[ch - 'a'])
                    solution[ch - 'a'] = 0;
                else
                    strokes++;
            }
        }

        //Judging all at one time
        int i;
        for (i = 0; i < 26; i++)
            if (solution[i])
                break;
        if (i == 26)
            ans = 0;
        else if (strokes >= 7)
            ans = 1;
        printAns(round, ans);
    }
    return 0;
}

void printAns(int r, int a)
{
    char ans[3][20] = {"You win.",
                     "You lose.",
                     "You chickened out."};
    printf("Round %d\n%s\n", r, ans[a]);
    return;
}
//scheme 1 Developed
#include <stdio.h>
#include <string.h>

void printAns(int, int);
int main(void)
{
    char puzzle[26];
    char ch;
    int strokes;
    int round, ans;

    while (scanf("%d", &round) == 1 && round != -1)
    {
        //Initiation
        strokes = 0;
        ans = 2;
        memset(puzzle, 0, sizeof(puzzle));

        //Input and processing
        getchar();
        while ((ch = getchar()) != '\n')
            puzzle[ch - 'a']++;
        while ((ch = getchar()) != '\n')
        {
            if (strokes >= 7)
                continue;
            //Each unique wrong guess only counts against the contestant once
            if (puzzle[ch - 'a'] != -1)
            {
                if (!puzzle[ch - 'a'])
                    strokes++;
                puzzle[ch - 'a'] = -1;
            }
        }

        //Judging all at one time
        int i;
        for (i = 0; i < 26; i++)
            if (puzzle[i] > 0)
                break;
        if (i == 26)
            ans = 0;
        else if (strokes >= 7)
            ans = 1;
        printAns(round, ans);
    }
    return 0;
}

void printAns(int r, int a)
{
    char ans[3][20] = {"You win.",
                     "You lose.",
                     "You chickened out."};
    printf("Round %d\n%s\n", r, ans[a]);
    return;
}
//scheme 2 Accepted
#include <stdio.h>
#include <string.h>

void printAns(int, int);
int main(void)
{
    int solution[26];
    int guess[26];
    char temp[112];
    int strokes;
    int round, ans;

    while (scanf("%d", &round) == 1 && round != -1)
    {
        //Initiation
        strokes = 0;
        ans = 2;
        memset(solution, 0, sizeof(solution));
        memset(guess, 0, sizeof(guess));

        //Input and processing
        scanf("%s", temp);
        char *p = temp;
        while (*p != 0)
            solution[*(p++) - 'a']++;
        scanf("%s", temp);
        p = temp;
        while (*p != 0)
        {
            //Each unique wrong guess only counts against the contestant once
            if (!guess[*p - 'a'])
            {
                guess[*p - 'a']++;
                if (solution[*p - 'a'])
                    solution[*p - 'a'] = 0;
                else
                    strokes++;
            }
            if (strokes >= 7)
                break;
            p++;
        }

        //Judging all at one time
        int i;
        for (i = 0; i < 26; i++)
            if (solution[i])
                break;
        if (i == 26)
            ans = 0;
        else if (strokes >= 7)
            ans = 1;
        printAns(round, ans);
    }
    return 0;
}

void printAns(int r, int a)
{
    char ans[3][20] = {"You win.",
                     "You lose.",
                     "You chickened out."};
    printf("Round %d\n%s\n", r, ans[a]);
    return;
}

  注:紫书上建议round不要命为round,因为有个库函数也叫round(在math.h里,用于浮点数的四舍五入取整),使用可能会引起混淆,用比如rnd或Round来代替,这是我疏忽了(通篇用的round…)。

  • 1
    点赞
  • 0
    收藏
    觉得还不错? 一键收藏
  • 0
    评论

“相关推荐”对你有帮助么?

  • 非常没帮助
  • 没帮助
  • 一般
  • 有帮助
  • 非常有帮助
提交
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值