【範例】ZeroJudge b147: NOIP2004 2.花生采摘
- 當範測需讀入的資料「分成多行」的情況,Python無法像C++一樣,透過鍵盤,把多行 sample input 一口氣 copy 再 paste 到 console 供程式讀取。
- 一行一行地進行 copy 再 paste,不但耗時,也容易出錯。
- 這時可以改用檔案讀取測資的方式,更方便地測試程式。
【Step-1】把sample input拷貝到一個新的檔案,存成”data.txt”
6 7 21
0 0 0 0 0 0 0
0 0 0 0 13 0 0
0 0 0 0 0 0 7
0 15 0 0 0 0 0
0 0 0 9 0 0 0
0 0 0 0 0 0 0
6 7 20
0 0 0 0 0 0 0
0 0 0 0 13 0 0
0 0 0 0 0 0 7
0 15 0 0 0 0 0
0 0 0 9 0 0 0
0 0 0 0 0 0 0
【Step-2】在原來的程式碼上方,加上下列程式碼:
- with open(“data.txt”, “r”) as f:
- 開啟檔案”data.txt”,屬性為”r” (read)
- f 為一個指向檔案”data.txt”的指標
- lines = f.readlines()
- 把整個檔案一次讀入,但維持原來的換行符號
- lines:為一個存放資料的list,每個元素即為每一行原始資料
#讀入整個檔案,有很多行
with open("data.txt", "r") as f:
lines = f.readlines()
print(lines)
[
'6 7 21\n',
'0 0 0 0 0 0 0\n',
'0 0 0 0 13 0 0\n',
'0 0 0 0 0 0 7\n',
'0 15 0 0 0 0 0\n',
'0 0 0 9 0 0 0\n',
'0 0 0 0 0 0 0\n',
'\n',
'6 7 20\n',
'0 0 0 0 0 0 0\n',
'0 0 0 0 13 0 0\n',
'0 0 0 0 0 0 7\n',
'0 15 0 0 0 0 0\n',
'0 0 0 9 0 0 0\n',
'0 0 0 0 0 0 0'
]
【Step-3】將原來程式碼中的 input( ) 換成 lines[idx],即可一次讀取一行。
- idx 代表目前要讀取的行號。每次讀完一行,記得把 idx 加 1。
- 程式執行後的結果,一樣會顯示在螢幕上。
#讀入整個檔案,有很多行
with open("data.txt", "r") as f:
lines = f.readlines()
# idx: 指向接著要讀取的行號,從0開始
idx = 0
#原來的程式, 改從檔案(取代鍵盤)輸入測資
while True:
try:
#M, N, K = map(int, input().split())
M, N, K = map(int, lines[idx].split()) #讀入一行,有三個整數
idx += 1 #行號加1
v = []
for i in range(M):
#tmp = list(map(int, input().split()))
tmp = list(map(int, lines[idx].split())) #讀入一行,有多個整數
idx += 1 #行號加1
for j, z in enumerate(tmp):
if (z > 0):
v.append((z, i+1, j+1))
v.sort(key=lambda x: -x[0])
x = 0
y = 0
ans = 0
for z, nx, ny in v:
if (x == 0):
dis = nx
else:
dis = abs(nx - x) + abs(ny - y)
if (K - dis > nx):
K = K - dis - 1
ans += z
x = nx
y = ny
else:
break
print(ans)
print()
#_ = input()
_ = lines[idx] #讀取一個空白行
idx += 1 #行號加1
except:
break