這邊不談解題思路,只討論 python 如何讀測資
由於題目提供的測資格式並不如題目所述(#3 的所有資料都在同一行)
所以我們需要調整輸入手段,基本邏輯是不變的,就是改一下讀資料的方式
模擬 c++ 的 std::cin
這樣就不會被因為沒有換行符導致 RE 了
import sys |
sys.stdin
是 python 的標準輸入流,當我們使用 input()
讀資料時,其實就是從標準輸入流中讀取資料,其作用約等於 stdin.readline().rstrip('\n')
這東西支援很多特別的讀取方式,讓你可以使用和 input()
不同的風格讀資料
至於標準輸入流具體是什麼這邊不細談,那東西可以寫另一篇文解釋了。
這邊我們要用的是 read()
這個方法,透過 sys.stdin.read()
使用它
作用是一口氣把標準輸入流中所有的資料全部讀進來,管它裡面有什麼牛鬼蛇神,全部都一口吞。
這時候我們會讀到類似這種格式的資料
"123\napple AC\nbanana AC\ncanda WA\n" |
可以注意到,不僅僅是空格,我們連換行符也一起讀進來了,這就是 read()
的效果,一口氣讀入所有資料
使用時要小心,資料量大時容易爆記憶體,不過這題沒那麼殘酷,可以放心使用。
這種格式資料要怎麼處理呢?
就用我們最熟悉的 str.split()
即可
如果不認識 split()
,請回頭去學一下基礎語法,關於字串處理的部分。
std.split()
可以幫助我們快速分割字串,除了空格外,也會根據換行符 \n
分割
使用後你會得到像這樣的資料
["123", "apple", "AC", "banana", "AC", "canda", "WA"] |
那些換行符和空格就都消失了,只留下那些我們真正需要關注的內容
需要注意的是這操作並不會自動轉換資料型態,所有的元素都是字串,如果你需要 int
,需要自己動手轉換
基本上操作到這程度就可以動手了,你可以跑 for
循環,間隔兩個元素去讀
例如:
n = ipt[0] |
但這樣可讀性很差,確實已經能用了,但......就不是很好讀
所以我更偏好的做法是加上 iter()
,模擬 c++ 的 std::cin
ipt = iter(ipt) |
iter()
會把一個可迭代的物件轉換成迭代器,然後使用 next()
一項一項的讀取裡面的內容
這樣的話就不用思考 i
是什麼, i + 1
又是什麼,而是用更具描述性的 name
, score
直接了解這裡存的具體是什麼資料
這是我個人個偏好的作法,要怎樣取捨就看各位
zerojudge 有時候會有這種格式有點奇怪的題目,這時就可以用這種方式靈活處理資料
程式的其他部分就自由發揮