iT邦幫忙

2

[C++][APCS] 棒球遊戲

題目出自 APCS 網站 > 歷次試題 > 2016-10-29_實作題 > 第四題 棒球遊戲
連結

解答僅供參考

解答:

#include <stdio.h>
#include <stdlib.h>
#include <string>

using namespace std;

#define SIZE 9

int main(void)
{
    int a[SIZE];
    string input[SIZE][5];
    char temp[3];
    int b;

    //讀取打擊結果
    for (int i = 0; i < SIZE; i++)
    {
        scanf("%d", &a[i]);
        for (int j = 0; j < a[i]; j++)
        {
            scanf("%s", temp);
            input[i][j] = temp;
        }
    }
    scanf("%d", &b);

    //計算分數
    int num = 0;       //打擊結果轉換後的值
    int point = 0;     //分數
    int out = 0;       //當局出局數
    int out_sum = 0;   //累積出局數
    int base[4] = {0}; //跑壘狀態,0壘上無人、1壘上有人,陣列索引分別對應,0:本壘, 1:一壘, 2:二壘, 3:三壘

    auto getNum = [&](string &point) {
        if (point == "1B")
            return 1;
        else if (point == "2B")
            return 2;
        else if (point == "3B")
            return 3;
        else if (point == "HR")
            return 4;
        return 0;
    };

    bool isOver = false;
    int index = 0;
    while (true)
    {
        for (int i = 0; i < SIZE; i++)
        {
            //超過最後一筆資料
            if (index > a[i])
            {
                isOver = true;
                break;
            }

            //將打擊結果轉換為數字
            num = getNum(input[i][index]);

            //出局
            if (num == 0)
            {
                out_sum++;
                out++;
            }
            //安打
            else
            {
                base[0] = 1; //將打擊者放在本壘
                for (int x = 3; x >= 0; x--)
                {
                    //如果壘上有人
                    if (base[x] == 1)
                    {
                        //回到本壘
                        if (x + num >= 4)
                        {
                            point++;
                        }
                        //未回到本壘
                        else
                        {
                            base[x + num] = 1;
                        }
                        base[x] = 0;
                    }
                }
            }
            //出局數達到結束條件
            if (out_sum == b)
            {
                isOver = true;
                break;
            }

            //達到三個出局數,清空跑壘狀態
            if (out == 3)
            {
                out = 0;
                base[0] = base[1] = base[2] = base[3] = 0;
            }
        }
        if (isOver)
        {
            break;
        }
        index++;
    }

    //印出結果
    printf("%d", point);

    system("pause");
    return 0;
}

輸入:

5 1B 1B FO GO 1B
5 1B 2B FO FO SO
4 SO HR SO 1B
4 FO FO FO HR
4 1B 1B 1B 1B
4 GO GO 3B GO
4 1B GO GO SO
4 SO GO 2B 2B
4 3B GO GO FO
3
0

輸出:

5 1B 1B FO GO 1B
5 1B 2B FO FO SO
4 SO HR SO 1B
4 FO FO FO HR
4 1B 1B 1B 1B
4 GO GO 3B GO
4 1B GO GO SO
4 SO GO 2B 2B
4 3B GO GO FO
6
5

說明:
以往寫C++處理字串都是使用C傳統的字元陣列,
這次想來練習一下 C++ 好用的 string 物件,
讀取字串因為還是使用 scanf 函數,所以另外宣告一個字元陣列來暫存讀進來的字串,
因為打擊結果都是長度為2的字串,所以這裡我宣告了一個長度為3的陣列,陣列的最後一位用來儲存字串的結尾符號 '\0'

接下來就是將暫存的字串寫入 string 陣列內,因為 string 有 operator = 所以可以直接將 C Style 的字元陣列賦值給 string,這個賦值會將暫存陣列內的字元複製到 string 的記憶體空間中。

接下來我寫了一個 getNum 函數,用來將打擊結果的字串轉換為數字。
1 -> 1壘打
2 -> 2壘打
3 -> 3壘打
4 -> 全壘打
0 -> 出局

再來講一下安打的地方,會先從 三壘 > 二壘 > 一壘 > 本壘,依次檢查每位跑壘者是否回到本壘,如果回到本壘就將分數加一,然後清除壘包上跑壘前的位置,如果沒有回到本壘,就將跑壘員移動到跑壘後的壘包上,並清除跑壘前的位置。

接著就是簡單的計分邏輯,就不再多做說明。


圖片
  直播研討會
圖片
{{ item.channelVendor }} {{ item.webinarstarted }} |
{{ formatDate(item.duration) }}
直播中

2 則留言

2
神Q超人
iT邦研究生 5 級 ‧ 2018-02-26 23:59:21

哇怎麼突然暴增3篇XD
話說我這幾天快被C++字元陣列搞死了/images/emoticon/emoticon06.gif
最後也沒解出來~~繞另外一條路走惹~_~

哈哈哈,我消失好久惹
我可以幫忙看看您的問題 XD

【**此則訊息已被站方移除**】
1
海綿寶寶
iT邦大神 1 級 ‧ 2018-03-01 17:51:50

練習也練了半年
這個月就來報名Google Code Jam
iT邦幫忙真正寫程式的人不多
會報名參加 code jam 的人更少

感謝大大的資訊
不過我想問個問題
登入後就算註冊成功嗎?
我找不到可以填資料的地方
/images/emoticon/emoticon70.gif

2018年的 code jam
三月六日才開始報名
建議你可以先看一下參加說明
最好先做一兩題2017 的題目以熟悉一下解題的流程
並且可以先寫好一些基本 function (讀題目的,寫答案的)

我今年也會參加
到時可以一起討論
人多比較有趣

了解,感謝海綿寶寶大大
/images/emoticon/emoticon41.gif

我要留言

立即登入留言