# APCS實作題2020年7月第2題:骰子 > 日期:2023年9月13日 > 作者:王一哲 > 題目來源:109年7月實作題第2題 > [ZeroJudge 題目連結](https://zerojudge.tw/ShowProblem?problemid=f580) <br /> ## 題目 ### 問題描述 給定 $n$ 個骰子排成一列,一開始都是點數 $1$ 朝上,點數 $4$ 朝前,點數 $2$ 朝右 (如圖1所示),另外骰子的展開圖如圖2所示。 <img height="55%" width="55%" src="https://imgur.com/fOiAuY6.png" style="display: block; margin-left: auto; margin-right: auto;"/> <div style="text-align:center">圖1</div> <br /> <img height="30%" width="30%" src="https://imgur.com/Ni0TjdI.png" style="display: block; margin-left: auto; margin-right: auto;"/> <div style="text-align:center">圖2</div> <br /> 接下來有 $m$ 次修改操作,每個操作包含兩個整數 $a$、$b$ - 若 $a$、$b$ 都是正整數,交換編號 $a$ 與編號 $b$ 的骰子的位置。 - 若 $b$ 為 $-1$,將編號 $a$ 的骰子**向前**旋轉。 - 若 $b$ 為 $-2$,將編號 $a$ 的骰子**向右**旋轉。 <img height="35%" width="35%" src="https://imgur.com/km7kecG.png" style="display: block; margin-left: auto; margin-right: auto;"/> <div style="text-align:center">向前旋轉</div> <br /> <img height="35%" width="35%" src="https://imgur.com/zAWZOv0.png" style="display: block; margin-left: auto; margin-right: auto;"/> <div style="text-align:center">向右旋轉</div> <br /> 在 $m$ 次操作結束之後,依序輸出編號 $1$ 到編號 $n$ 的骰子朝上的點數。 <br /> ### 輸入格式 第一行包含兩個正整數 $n$、$m$($1 \leq n \leq 20, ~1 \leq m \leq 100$)。 接下來 $m$ 行每行有兩個整數,第 $i$ 行的兩個正整數表示第 $i$ 次操作。 <br /> ### 輸出格式 在一行輸出 $n$ 個數字以空格分隔,第 $i$ 個數字表示編號 $i$ 的骰子最後朝上的點數。 <br /> ### 範例一:輸入 ``` 1 2 1 -2 1 -1 ``` ### 範例一:正確輸出 ``` 3 ``` <br /> ### 範例二:輸入 ``` 3 3 2 -1 3 -2 3 1 ``` ### 範例二:正確輸出 ``` 5 3 1 ``` <br /> ## Python 程式碼 ### 方法1:使用二維串列 於 ZeroJudge 測試結果,最長運算時間約為 43 ms,使用記憶體最多約為 3.4 MB,通過測試。 ```python= # 自訂函式向前旋轉 def rotateF(dice): tmp = dice[0] dice[0] = dice[4] dice[4] = dice[1] dice[1] = dice[2] dice[2] = tmp return dice # 自訂函式向右旋轉 def rotateR(dice): tmp = dice[0] dice[0] = dice[5] dice[5] = dice[1] dice[1] = dice[3] dice[3] = tmp return dice # 解題過程 n, m = map(int, input().split()) # 讀取資料 n, m dices = [[1, 6, 4, 2, 3, 5] for _ in range(n)] # 儲存骰子每面數值的二維串列,順序為上、下、前、右、後、左 for _ in range(m): # 讀取 m 行操作資料 a, b = map(int, input().split()) if b > 0: # 交換骰子 dices[a-1], dices[b-1] = dices[b-1], dices[a-1] elif b == -1: # 向前旋轉 dices[a-1] = rotateF(dices[a-1]) elif b == -2: # 向右旋轉 dices[a-1] = rotateR(dices[a-1]) for i in range(n): # 印出每顆骰子朝上的點數 print(dices[i][0], end=" " if i < n-1 else "\n") ``` <br /><br /> ### 方法2:使用自訂類別 於 ZeroJudge 測試結果,最長運算時間約為 21 ms,使用記憶體最多約為 3.4 MB,通過測試。 ```python= # 自訂類別 class Dice: def __init__(self): self.top = 1 self.bottom = 6 self.front = 4 self.right = 2 self.back = 3 self.left = 5 def rotateF(self): # 自訂函式向前旋轉 tmp = self.top self.top = self.back self.back = self.bottom self.bottom = self.front self.front = tmp def rotateR(self): # 自訂函式向右旋轉 tmp = self.top self.top = self.left self.left = self.bottom self.bottom = self.right self.right = tmp # 解題過程 n, m = map(int, input().split()) # 讀取資料 n, m dices = [Dice() for _ in range(n)] # 儲存骰子資料的一維串列 for _ in range(m): # 讀取 m 行操作資料 a, b = map(int, input().split()) if b > 0: # 交換骰子 dices[a-1], dices[b-1] = dices[b-1], dices[a-1] elif b == -1: # 向前旋轉 dices[a-1].rotateF() elif b == -2: # 向右旋轉 dices[a-1].rotateR() for i in range(n): # 印出每顆骰子朝上的點數 print(dices[i].top, end=" " if i < n-1 else "\n") ``` <br /><br /> ## C++ 程式碼 ### 方法1:使用二維陣列 於 ZeroJudge 測試結果,最長運算時間約為 3 ms,使用記憶體最多約為 328 kB,通過測試。 ```cpp= #include <iostream> #include <algorithm> using namespace std; // 自訂函式向前旋轉 void rotateF(int* dice) { int tmp = dice[0]; dice[0] = dice[4]; dice[4] = dice[1]; dice[1] = dice[2]; dice[2] = tmp; } // 自訂函式向右旋轉 void rotateR(int* dice) { int tmp = dice[0]; dice[0] = dice[5]; dice[5] = dice[1]; dice[1] = dice[3]; dice[3] = tmp; } int main() { // 解題過程 int n, m; cin >> n >> m; // 讀取資料 n, m int dices[n][6]; for(int i=0; i<n; i++) { // 儲存骰子每面數值的二維陣列,順序為上、下、前、右、後、左 dices[i][0] = 1; dices[i][1] = 6; dices[i][2] = 4; dices[i][3] = 2; dices[i][4] = 3; dices[i][5] = 5; } for(int i=0; i<m; i++) { // 讀取 m 行操作資料 int a, b; cin >> a >> b; if (b > 0) { // 交換骰子 swap(dices[a-1], dices[b-1]); } else if (b == -1) { // 向前旋轉 rotateF(dices[a-1]); } else if (b == -2) { // 向右旋轉 rotateR(dices[a-1]); } } for(int i=0; i<n; i++) { // 印出每顆骰子朝上的點數 cout << dices[i][0] << " \n"[i == n-1]; } return 0; } ``` <br /><br /> ### 方法2:使用自訂類別 於 ZeroJudge 測試結果,最長運算時間約為 3 ms,使用記憶體最多約為 340 kB,通過測試。 ```cpp= #include <iostream> #include <algorithm> using namespace std; class Dice { public: int top = 1, bottom = 6, front = 4, right = 2, back = 3, left = 5; // 自訂函式向前旋轉 void rotateF() { int tmp = top; top = back; back = bottom; bottom = front; front = tmp; } // 自訂函式向右旋轉 void rotateR() { int tmp = top; top = left; left = bottom; bottom = right; right = tmp; } }; int main() { // 解題過程 int n, m; cin >> n >> m; // 讀取資料 n, m Dice dices[n]; for(int i=0; i<m; i++) { // 讀取 m 行操作資料 int a, b; cin >> a >> b; if (b > 0) { // 交換骰子 swap(dices[a-1], dices[b-1]); } else if (b == -1) { // 向前旋轉 dices[a-1].rotateF(); } else if (b == -2) { // 向右旋轉 dices[a-1].rotateR(); } } for(int i=0; i<n; i++) { // 印出每顆骰子朝上的點數 cout << dices[i].top << " \n"[i == n-1]; } return 0; } ``` <br /><br /> --- ###### tags:`APCS`、`Python`、`C++`