# APCS 2023/10/22 python題解 ## 1. 機械鼠 https://zerojudge.tw/ShowProblem?problemid=m370 - 利用filter函數找出大於x的食物個數,再判斷往左或往右移動可以吃到更多食物 ```python # 輸入x為老鼠起始位置,n為食物數量,l為食物位置 x, n = map(int, input().split()) l = list(map(int, input().split())) # 使用filter找出大於x的食物個數 temp = len(list(filter(lambda i: i>x, l))) # 判斷往左或往右可以吃到更多食物 if temp > n // 2: print(temp, max(l)) # 往右吃更多 else: print(n - temp, min(l)) # 往左吃更多 ``` ## 2. 卡牌遊戲 https://zerojudge.tw/ShowProblem?problemid=m371 - 記錄每個數字出現位置,判斷可以消除的組合並累加分數 ```python from sys import stdin e = stdin.readline # 輸入表格大小 m, n = map(int, e().split()) # 建立表格 l = [list(map(int, e().split())) for _ in range(m)] # 記錄每個數字出現位置 pos = {} for i in range(m): for j in range(n): k = l[i][j] if k not in pos: pos[k] = [] if pos[k]: x, y = pos[k][0] # 判斷是否可以相互消除 if i != x and j != y: del pos[k] continue pos[k].append((i, j)) # 檢查每個數字的兩個位置是否可以相互消除 # 如果可以就刪除位置記錄並累加分數 ans = 0 while True: for k in pos: s, t = pos[k] a, b = s c, d = t if a == c: # 判斷中間是否有阻礙 for i in range(b+1, d): if l[a][i] >= 0: break else: ans += k l[a][b] = -1 l[c][d] = -1 del pos[k] break else: for i in range(a+1, c): if l[i][b] >= 0: break else: ans += k l[a][b] = -1 l[c][d] = -1 del pos[k] break else: break print(ans) ``` ## 3. 搬家 https://zerojudge.tw/ShowProblem?problemid=m372 - DFS搜尋每個連通塊大小並記錄最大值 ```python from sys import stdin def e(): return stdin.readline().strip() # 定義水管方向對應表 T = {"F":(0, 1, 0, 1), "H":(0, 0, 1, 1), "7":(0, 1, 1, 0), "I":(1, 1, 0, 0), "X":(1, 1, 1, 1), "L":(1, 0, 0, 1), "J":(1, 0, 1, 0), "0":(0, 0, 0, 0) } m, n = map(int, e().split()) l = [list(e()+"0") for _ in range(m)] + [["0"]*n] ans = 0 d = [(-1, 0), (1, 0), (0, -1), (0, 1)] # DFS搜尋每個連通塊 for i in range(m): for j in range(n): if l[i][j] == "0": continue stack = [(i, j)] c = 0 while stack: i, j = stack.pop() if l[i][j] == "0": continue t = T[l[i][j]] l[i][j] = "0" c += 1 for idx in range(4): if not t[idx]: continue di, dj = d[idx] ni, nj = i + di, j + dj if T[l[ni][nj]][idx^1]: stack.append((ni, nj)) # 記錄最大連通塊大小 ans = max(c, ans) print(ans) ``` ## 4. 投資遊戲 https://zerojudge.tw/ShowProblem?problemid=m373 - 動態規劃計算使用每個金牌的最大收益 ```python def main(): from sys import stdin, stdout e = stdin.readline n, k = map(int, e().split()) l = list(map(int, e().split())) # 建立dp table # dp[i][j] = 使用i個金牌,前j天的最大收益 dp = [[0]*n for i in range(k+1)] for i in range(n): dp[0][i] = max(dp[0][i-1], 0) + l[i] for i in range(1, k+1): dp[i][0] = max(0, dp[i-1][0]) for j in range(1, n): # dp轉移式 dp[i][j] = max(dp[i][j-1] + l[j], dp[i-1][j-1]) # 輸出使用所有金牌的最大收益 stdout.write(str(max(dp[-1]+[0]))) main() ```