# 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++`