Editorial for 籃球比賽 (APCS 2019-06 初級)


簡潔題意

兩場籃球賽,每場主隊、客隊各打四局。輸入固定四行、每行四個 \(0\) 到 \(100\) 的整數,依序是「第一場主隊、第一場客隊、第二場主隊、第二場客隊」的四局得分。對每場輸出一行 主隊總分:客隊總分(半形冒號),最後依兩場勝負輸出 Win(主隊兩勝)、Lose(客隊兩勝)或 Tie(各勝一場)。題目保證單場不會同分。(APCS 逐筆給分。)

照題意模擬:兩場比賽做的事一模一樣

這題沒有演算法,純粹照題意做:每一場都是「主隊四局加總、客隊四局加總、印比數、看誰贏」——兩場做的事完全相同,所以外面包一個跑兩次的 for 迴圈(4.3),一場一場處理。

每場裡面,四局加總就是最基本的累加器寫法(4.2 的範例用過同一招):home 從 \(0\) 開始、>> 讀一局加一局。這裡有個值得養成的習慣:homeaway 宣告在迴圈裡面——區域變數每一輪都是全新的一份,第二場自動從 \(0\) 開始,「上一場的總分殘留到下一場」這種 bug 從結構上就不可能發生。

勝負判斷只要 home > away(題目保證不平手,不用管等於的情況),用 homeWins 數主隊贏了幾場:兩場全贏印 Win、全輸印 Lose、一勝一負印 Tie3.5if / else if / else)。完整程式:

#include <iostream>
using namespace std;

int main() {
    int homeWins = 0;              // 主隊贏了幾場
    for (int game = 0; game < 2; game++) {   // 兩場比賽,一場一場處理
        int home = 0, away = 0;    // 這一場兩隊的總分(宣告在迴圈裡,每場自動從 0 開始)
        for (int j = 0; j < 4; j++) {
            int x;
            cin >> x;
            home = home + x;       // 主隊四局加總
        }
        for (int j = 0; j < 4; j++) {
            int x;
            cin >> x;
            away = away + x;       // 客隊四局加總
        }
        cout << home << ":" << away << endl;   // 比數:半形冒號、前後不加空白
        if (home > away) {
            homeWins = homeWins + 1;           // 題目保證不平手,比大小就知道誰贏
        }
    }

    if (homeWins == 2) {
        cout << "Win" << endl;
    } else if (homeWins == 0) {
        cout << "Lose" << endl;
    } else {
        cout << "Tie" << endl;
    }
    return 0;
}

拿範例走一遍:每行都是 \(87 \times 4 = 348\) 對 \(78 \times 4 = 312\),兩場比數都是 348:312、主隊兩勝,最後印 Win

測過再交:範例只給了 Win,另外兩種要自己補

最後一行有三種可能的輸出,唯一的範例卻只涵蓋 Win——你的 LoseTie 分支對不對,範例完全沒測到。自己補測資很簡單:把範例的行序調換就能變出另外兩種局面——主客兩行對調就是 Lose;只對調第二場的兩行,就是一勝一負的 Tie

餵什麼 正確輸出 這一筆在測什麼
範例的主、客行整組對調 312:348312:348Lose 客隊兩勝的分支
只對調第二場的兩行 348:312312:348Tie 一勝一負的分支
一隊四局全 \(100\)、另一隊全 \(0\) 400:0400:0Win 總分的最大值(\(400\) 也遠在 int 範圍內)
0 0 0 10 0 0 0(兩場皆同) 1:01:0Win 只差 \(1\) 分的最小差距

四筆都親眼看過正確,這題就穩了。

常犯錯誤
  1. 總分變數宣告在迴圈外、忘了每場歸零homeaway 放在迴圈外面的話,第二場會繼續往第一場的總分上加——範例的第二行會印出 696:624,當場現形。像主文那樣宣告在迴圈裡面,每場自動從 \(0\) 開始,最省心。
  2. 比數格式:半形冒號 :、前後都不加空白。印成 348 : 312(冒號旁有空白)或用了全形冒號 ,都跟正解不是同一回事、會 WA——這不是「行末空白」那種會被寬容的差異。
  3. 主客印反:輸出是「主隊總分在前、客隊在後」。對調的話範例第一行就變 312:348,範例當場抓到。
  4. WinLose 的視角搞反Win主隊兩勝。反過來寫的話,範例最後一行會印出 Lose(正確是 Win),範例當場抓到。
  5. Tie 想成單場同分:題目保證每場都分得出勝負,單場不會同分;最後一行的 Tie 指的是「兩場各勝一場」。不需要為單場平手寫任何處理。