# APCS實作題2020年1月第1題:猜拳 > 日期:2023年9月18日 > 作者:王一哲 > 題目來源:109年1月實作題第1題 > [ZeroJudge 題目連結](https://zerojudge.tw/ShowProblem?problemid=h026) <br /> ## 題目 ### 問題描述 幼稚園的絲絲很喜歡跟哥哥玩猜拳,因為這是他少數有機會贏哥哥的遊戲。每天只要一回家,絲絲就要哥哥陪他猜拳。為了戰勝哥哥,絲絲每天在幼稚園時都會花好多時間研究出拳的策略,並將預計要出的拳寫在紙上。但是哥哥上了國中以後功課越來越多,沒有空先思考要出什麼拳,於是哥哥決定根據絲絲出的拳來決定該如何出拳。 每天哥哥只要決定第一次猜拳的狀況 $F$,接下來他的猜拳策略如下: - 如果絲絲連續兩輪出了一樣的拳,下一輪他就會出打敗絲絲前兩輪的拳。 - 否則,他下一輪會出跟絲絲前一輪一樣的拳。 請你寫一個程式模擬兩人遊戲過程與結果。 <br /> ### 輸入說明 第一行輸入哥哥第一輪要出的拳 $F$。 第二行輸入妹妹準備的數量 $N$。 第三行依序輸入妹妹準備出的拳 $y_1, y_2, \dots, y_N$,以空格隔開。 測資範圍如下: - 所有的出拳皆為 0, 2, 5(0指石頭,2指剪刀,5指布) - $N \leq 10$ 本題包含三個子題組,每個子題組配分如下: - 第1子題組共20分:$N = 1$ - 第2子題組共20分:$N = 2$,$y_1 \neq y_2$。 - 第3子題組共60分:無額外限制。 <br /> ### 輸出說明 輸出有一行,依序輸出哥哥每一回合猜的拳,以空格隔開。並在冒號後輸出第幾回合分出勝負。 - 若在第 $k$ 輪時哥哥贏了,輸出 **: Won at round k** - 若在第 $k$ 輪時哥哥輸了,輸出 **: Lost at round k** - 若比完 $N$ 輪仍然平手,輸出 **: Drew at round N** <br /> ### 範例一:輸入 ``` 0 4 2 5 0 2 ``` ### 範例一:正確輸出 ``` 0 : Won at round 1 ``` <br /> ### 範例二:輸入 ``` 2 2 2 0 ``` ### 範例二:正確輸出 ``` 2 2 : Lost at round 2 ``` <br /> ### 範例三:輸入 ``` 5 4 5 5 0 0 ``` ### 範例三:正確輸出 ``` 5 5 2 : Lost at round 3 ``` <br /> ### 範例四:輸入 ``` 5 6 5 5 2 2 0 0 ``` ### 範例四:正確輸出 ``` 5 5 2 2 0 0 : Drew at round 6 ``` <br /> ## Python 程式碼 於 ZeroJudge 測試結果,最長運算時間約為 24 ms,使用記憶體最多約為 3.4 MB,通過測試。 ```python= F = int(input()) # 讀取F N = int(input()) # 讀取N ys = list(map(int, input().split())) # 讀取 y1 ~ yN draw = True # 是否平手 for i in range(N): # 依序讀取 y1 ~ yN print(F, end=" ") # 印出 F # 哥哥獲勝 if (F == 0 and ys[i] == 2) or (F == 2 and ys[i] == 5) or (F == 5 and ys[i] == 0): print(": Won at round {:d}".format(i+1)) draw = False break # 哥哥輸掉 elif (F == 2 and ys[i] == 0) or (F == 5 and ys[i] == 2) or (F == 0 and ys[i] == 5): print(": Lost at round {:d}".format(i+1)) draw = False break # 哥哥依照妹妹出拳的狀態決定下次要出的拳 if i >= 1 and ys[i-1] == ys[i]: if ys[i] == 0: F = 5 elif ys[i] == 2: F = 0 elif ys[i] == 5: F = 2 else: if ys[i] == 0: F = 0 elif ys[i] == 2: F = 2 elif ys[i] == 5: F = 5 # 如果平手,印出以下內容 if draw: print(": Drew at round {:d}".format(N)) ``` <br /><br /> ## C++ 程式碼 於 ZeroJudge 測試結果,最長運算時間約為 3 ms,使用記憶體最多約為 344 kB,通過測試。 ```cpp= #include <iostream> using namespace std; int main() { int F; cin >> F; // 讀取F int N; cin >> N; // 讀取N int ys[N]; for(int i=0; i<N; i++ ) cin >> ys[i]; // 讀取 y1 ~ yN bool draw = true; // 是否平手 for(int i=0; i<N; i++ ) { // 依序讀取 y1 ~ yN cout << F << " "; // 印出 F if ((F == 0 && ys[i] == 2) || (F == 2 && ys[i] == 5) || (F == 5 && ys[i] == 0)) { // 哥哥獲勝 cout << ": Won at round " << i+1 << endl; draw = false; break; } else if ((F == 2 && ys[i] == 0) || (F == 5 && ys[i] == 2) || (F == 0 && ys[i] == 5)) { // 哥哥輸掉 cout << ": Lost at round " << i+1 << endl; draw = false; break; } /* 哥哥依照妹妹出拳的狀態決定下次要出的拳 */ if (i >= 1 && ys[i-1] == ys[i]) { if (ys[i] == 0) F = 5; else if (ys[i] == 2) F = 0; else if (ys[i] == 5) F = 2; } else { if (ys[i] == 0) F = 0; else if (ys[i] == 2) F = 2; else if (ys[i] == 5) F = 5; } } /* 如果平手,印出以下內容 */ if (draw) cout << ": Drew at round " << N << endl; return 0; } ``` <br /><br /> --- ###### tags:`APCS`、`Python`、`C++`
×
Sign in
Email
Password
Forgot password
or
Sign in via Google
Sign in via Facebook
Sign in via X(Twitter)
Sign in via GitHub
Sign in via Dropbox
Sign in with Wallet
Wallet (
)
Connect another wallet
Continue with a different method
New to HackMD?
Sign up
By signing in, you agree to our
terms of service
.