這是參考高中生程式解讀系統的題目,答案不是最佳解,只是其中一種方法,有問題歡迎提出!!
t090.1. 踩地雷(的反向版)
這題因為我目前還沒有遇到記得完整題目的人,所以就重新寫了一下題目敘述,不過搜尋中心相關的操作是真的。
如果有人還記得題目內容的話請站內信告訴我,謝謝。
給定一張經過「搜尋」後的結果矩陣。每個格子的數值會依照該格是否為搜尋中心,以及是否位於第一列或最後一列,由原本的地雷數 x 轉換而成:
搜尋中心且位於第一列或最後一列:2x + 1 搜尋中心且不在第一列或最後一列:2x 非搜尋中心且位於第一列或最後一列:x + 1 非搜尋中心且不在第一列或最後一列:x 已知所有格子的搜尋結果與搜尋中心位置,請反推出原本的地雷矩陣。
輸入說明
第一行有兩個整數 n, m,代表地雷矩陣的大小為 n 行 m 列。 接下來 n 行,每行有 m 個整數,代表搜尋後的結果矩陣。 再接下來 n 行,每行有 m 個整數,代表搜尋中心矩陣,其中 1 表示該位置為搜尋中心,0 表示不是搜尋中心。
保證輸入資料可以唯一反推出原本的地雷矩陣。 1 ≤ n, m ≤ 1000 所有數字(包含運算過程)都可以用正整數(unsigned int)儲存。
輸出說明
輸出建好的圖
範例輸入 #1
5 7
33 9 6 3 39 8 21
15 0 20 20 18 13 1
8 0 15 14 10 2 18
28 28 7 14 34 6 28
6 25 39 8 13 9 1
1 0 0 1 1 0 1
0 0 0 1 0 0 0
1 1 0 0 1 1 0
1 1 0 1 1 1 1
0 1 1 0 0 1 1
範例輸出 #1
16 8 5 1 19 7 10
15 0 20 10 18 13 1
4 0 15 14 5 1 18
14 14 7 7 17 3 14
5 12 19 7 12 4 0
0.9s, 26.8MB(題目提供者題解為:0.8s,18.4MB) 題解:
n,m = map(int,input().split())
n_list = [list(map(int,input().split())) for _ in range(n)]
n2_list = [list(map(int,input().split())) for _ in range(n)]
for i in range(n):
ans = []
for j in range(m):
if n2_list[i][j] == 1:
if i == 0 or i == n-1:
ans.append((n_list[i][j]-1)//2)
else:
ans.append(n_list[i][j]//2)
elif n2_list[i][j] == 0:
if i == 0 or i == n-1:
ans.append((n_list[i][j]-1))
else:
ans.append(n_list[i][j])
print(*ans)
t100.2. 猜字遊戲
你的任務是要把給定的字串變成謎題
地圖預設是米字號(*)
如果新字串會超出地圖就捨棄
如果新字串跟其他字串重疊到,然後重疊到的部分的字母不一樣的話,也捨棄新字串。
輸出的表中除了頭尾的字母外,其他都變成底線 (_)
輸入說明
第一行會有兩個數字 r,c,n 代表網格的大小與字串數量 接下來會有 n 行,每行有 x,y,d,w 代表在 x,y 填入(d = 0 左往右 d =1上往下)
1 ≤ r, c ≤ 200 1 ≤ n ≤ 1000 字串長度必小於最大長寬且一定是大寫字母
輸出說明
建好之後的圖
範例輸入 #1
1 15 2
1 1 0 PYTHON
1 9 0 JAVA
範例輸出 #1
P____N**J__A***
範例輸入 #2
5 5 5
3 3 1 DFQ
3 4 0 XKB
2 1 0 HEE
1 2 0 PRSY
1 1 1 INR
範例輸出 #2
*P__Y
H_E**
**D**
**_**
**Q**
30ms, 10.4MB(題目提供者提解是26ms,9.9MB ) 題解:
r, c, n = map(int, input().split())
grid = [["*"] * c for _ in range(r)] # 存完整字母,用來判斷重疊
show = [["*"] * c for _ in range(r)] # 輸出用
for _ in range(n):
y, x, d, w = input().split() # 第一個數字是 y(列),與範例吻合
x, y = int(x) - 1, int(y) - 1
L = len(w)
if d == "0":
if x < 0 or y < 0 or y >= r or x + L - 1 >= c:
continue
cells = [(y, x + i) for i in range(L)]
else:
if x < 0 or y < 0 or x >= c or y + L - 1 >= r:
continue
cells = [(y + i, x) for i in range(L)]
# 只有重疊處「字母不同」才捨棄
if any(grid[a][b] not in ("*", w[i]) for i, (a, b) in enumerate(cells)):
continue
for i, (a, b) in enumerate(cells):
grid[a][b] = w[i]
if i == 0 or i == L - 1: # 頭尾字母一定顯示
show[a][b] = w[i]
elif show[a][b] == "*": # 中間:原為 * 才填底線
show[a][b] = "_"
print("\n".join("".join(row) for row in show))
t101.3. 運動比賽
為了鼓勵大家養成運動習慣,學校舉辦了一場為期 k 天的運動比賽,共有 n 位選手參加。選手每天可以透過走路、跑步與騎腳踏車獲得積分。
每天的運動積分計算方式如下:
每走路 10 分鐘,可獲得 a 分。 每跑步 10 分鐘,可獲得 b 分。 每騎腳踏車 10 分鐘,可獲得 c 分。 每天活動結束後,根據當天的運動積分進行額外加分:
當天運動積分最高的選手,總積分額外增加 d 分。 當天運動積分最低的選手,總積分扣除 e 分。 從第二天開始,若某位選手當天的運動積分比前一天高,則總積分額外增加 f 分。 注意:上述加分與扣分皆直接影響選手的總積分,而不是當天的運動積分。
比賽開始時,所有選手的總積分皆為 0 分。請計算所有比賽結束後每位選手的總積分,並輸出總積分最高的選手編號及其總積分。
輸入說明
第一行有兩個數字 n,k 代表有n個人比了k天
第二行有a,b,c,d,e,f 代表走路10分鐘有a分,跑步10分鐘有b分,騎腳踏車10分鐘有c分,日積分第一名總積分加d分,最後一名扣 e 分,如果(第二天開始)當天的分數比前一天高的話總積分就加f 分。 接下來會有 n 行,每行會有 3k 個數字,代表該為選手每天每項的運動時間(分鐘)
3 ≤ n, k ≤ 1000 1 ≤ a,b,c ≤ 10 0 ≤ d, e, f ≤ 1000 保證所有輸入資料及計算過程中的數值皆可使用 32 位元有號整數(int)儲存。
輸出說明
輸出最高分的人的編號(從1開始)跟他的分數
範例輸入 #1
3 3
6 4 6 1 3 6
84 21 18 5 80 92 37 64 23
13 1 44 50 92 83 75 92 67
70 86 28 80 63 90 85 75 40
範例輸出 #1
3 320
1.2s, 50.5MB(題目提供者題解為:1.4s,48.8MB) 題解:
n,k = map(int,input().split())
a,b,c,d,e,f = map(int,input().split())
ans_list = [0]*n
date = []
for i in range(n):
Q = list(map(int,input().split()))
idx = 0
N_day = []
temp = float("inf")
for j in range(k):
N_day.append((Q[idx]//10)*a + (Q[idx+1]//10)*b + (Q[idx+2]//10)*c);idx+=3
if N_day[j] > temp: #進步獎
ans_list[i] += f
temp = N_day[j]
ans_list[i] += sum(N_day)
date.append(N_day)
for t in zip(*date): #每日最高/最低
ans_list[t.index(max(t))] += d
ans_list[t.index(min(t))] -= e
g = max(ans_list) #直接找最小值
print(ans_list.index(g)+1,g)
