# APCS實作題2023年6月第1題:路徑偵測 > 日期:2023年9月26日 > 作者:王一哲 > 題目來源:112年6月實作題第1題 > [ZeroJudge 題目連結](https://zerojudge.tw/ShowProblem?problemid=k731) <br /> ## 題目 ### 問題描述 給一個二維平面,座標如同數學的二維座標(Y正為北,X正為東)。起始位置在 (0, 0),接下來會有 $n$ 個座標,你需要按照這些座標點的順序移動,保證僅會垂直或水平方向上移動,不會斜向移動,且第一個點保證一定是X軸正的位置(初始方向向右)。 請輸出這條路徑中,左轉、右轉、迴轉的個數分別為多少。 配分 - 60%:$n = 2$ - 40%:$n \leq 100$ <br /> ### 輸入說明 第一行輸入一個正整數 $n$,接下來有 $n$ 行,每一行都有兩個正整數 $x, y$。保證的是相鄰兩個點的座標差值不超過 100。 <br /> ### 輸出說明 輸出三個正整數,分別代表左轉、右轉、迴轉的次數。 <br /> ### 範例一:輸入 ``` 2 2 0 2 1 ``` ### 範例一:正確輸出 ``` 1 0 0 ``` <br /> ### 範例二:輸入 ``` 9 4 0 4 9 4 8 4 10 4 2 4 3 6 3 6 10 6 9 ``` ### 範例二:正確輸出 ``` 2 1 5 ``` <br /> ## Python 程式碼 於 ZeroJudge 測試結果,最長運算時間約為 23 ms,使用記憶體最多約為 3.4 MB,通過測試。 ```python= def findDir(xc, yc, xp, yp): # 回傳前進方向 if xc > xp and yc == yp: return 1 # 向右 elif xc == xp and yc > yp: return 2 # 向上 elif xc < xp and yc == yp: return 3 # 向左 elif xc == xp and yc < yp: return 4 # 向下 else: return 0 def turn(dc, dp): # 回傳轉彎種類 if (dp == 1 and dc == 2) or (dp == 2 and dc == 3) or (dp == 3 and dc == 4) or (dp == 4 and dc == 1): return 1 # 左轉 elif (dp == 1 and dc == 4) or (dp == 4 and dc == 3) or (dp == 3 and dc == 2) or (dp == 2 and dc == 1): return 2 # 右轉 elif (dp == 1 and dc == 3) or (dp == 3 and dc == 1) or (dp == 2 and dc == 4) or (dp == 4 and dc == 2): return 3 # 迴轉 else: return 0 n = int(input()) # 讀取資料行數 xp, yp = 0, 0 # 前一次的位置 L, R, U = 0, 0, 0 # 分別為左轉、右轉、迴轉次數 xc, yc = map(int, input().split()) # 目前的位置 dp = findDir(xc, yc, xp, yp) # 前一次的前進方向 xp, yp = xc, yc # 更新 xp, yp for _ in range(1, n): # 依序讀取第 2 ~ n 筆資料 xc, yc = map(int, input().split()) # 目前的位置 dc = findDir(xc, yc, xp, yp) # 找出目前的前進方向 T = turn(dc, dp) # 由前進方向找出轉彎種類 if T == 1: L += 1 # 右轉 elif T == 2: R += 1 # 左轉 elif T == 3: U += 1 # 迴轉 xp, yp, dp = xc, yc, dc # 更新 xp, yp, yp print("{:d} {:d} {:d}".format(L, R, U)) # 印出答案 ``` <br /><br /> ## C++ 程式碼 於 ZeroJudge 測試結果,最長運算時間約為 3 ms,使用記憶體最多約為 332 kB,通過測試。 ```cpp= #include <iostream> using namespace std; int findDir(int xc, int yc, int xp, int yp) { // 回傳前進方向 if (xc > xp && yc == yp) return 1; // 向右 else if (xc == xp && yc > yp) return 2; // 向上 else if (xc < xp && yc == yp) return 3; // 向左 else if (xc == xp && yc < yp) return 4; // 向下 else return 0; } int turn(int dc, int dp) { // 回傳轉彎種類 if ((dp == 1 && dc == 2) || (dp == 2 && dc == 3) || (dp == 3 && dc == 4) || (dp == 4 && dc == 1)) return 1; // 左轉 else if ((dp == 1 && dc == 4) || (dp == 4 && dc == 3) || (dp == 3 && dc == 2) || (dp == 2 && dc == 1)) return 2; // 右轉 else if ((dp == 1 && dc == 3) || (dp == 3 && dc == 1) || (dp == 2 && dc == 4) || (dp == 4 && dc == 2)) return 3; // 迴轉 else return 0; } int main() { int n; cin >> n; // 讀取資料行數 int xp = 0, yp = 0; // 前一次的位置 int L = 0, R = 0, U = 0; // 分別為左轉、右轉、迴轉次數 int xc, yc; cin >> xc >> yc; // 目前的位置 int dp, dc, T; // 分別為前一次的前進方向、目前的前進方向、轉彎種類 dp = findDir(xc, yc, xp, yp); // 前一次的前進方向 xp = xc; yp = yc; // 更新 xp, yp for(int i=1; i<n; i++) { // 依序讀取第 2 ~ n 筆資料 cin >> xc >> yc; // 目前的位置 dc = findDir(xc, yc, xp, yp); // 找出目前的前進方向 T = turn(dc, dp); // 由前進方向找出轉彎種類 if (T == 1) L++; // 右轉 else if (T == 2) R++; // 左轉 else if (T == 3) U++; // 迴轉 xp = xc; yp = yc; dp = dc; // 更新 xp, yp, yp } cout << L << " " << R << " " << U << endl; // 印出答案 return 0; } ``` <br /><br /> --- ###### tags:`APCS`、`Python`、`C++`