本題改自 112 CS a.k.a. 台大資工 2014 年二階程式題(ZeroJudge e934: pD. DNA 轉錄)。當然,原題沒有那麼噁心喇 XDD
本題貌似非常單純,乍看之下無論用 switch-case 或 map 都可以秒殺。然而字串長度最高達 $20000000$,此時字串的讀取及儲存或成為問題。不過,普通解應可獲得 90% 分數。
那麼這時我們就需要針對輸出入進行優化。
傳統刻板印象中,C++ 的 cin, cout 等「流」的操作往往被認為是慢於
的 printf(), scanf(),有兩大原因:
‘\n’
再 flush,在競賽中也是不必要的理論上 cin, cout 應該略快,因為 template 在編譯時期就已經決定,反觀 scanf(), printf() 在執行時期才處理 format string。
當然,使用 getchar(), putchar() 每次讀取單個字元會更快。
此外,Linux 可以在原有 C 的 IO 函式後方加上 "_unlocked" 以呼叫非標準的執行緒不安全版本,例如 getchar_unlocked(), putchar_unlocked()。
其他邪門歪道的技巧(?)像是一次 fread_unlocked() 一堆字元的頂多 #8
從 3ms 變為 2ms,整體影響不大。nmap 之類的我不會,看有迷有人要研究一下囉 o'_'o
以下簡表列出各種優化的費時供參:
|
Time (#9, #8) |
cin, cout |
TLE, 58ms |
printf(), scanf() |
TLE, 5ms |
sync_with_stdio(false) | cin.tie(nullptr) cin.get(), cout |
0.9s, 5ms |
getchar(), cout |
0.8s, 5ms |
scanf(), putchar() | 0.7s, 4ms |
sync_with_stdio(false) & cin.tie(nullptr) cin.get(), cout |
0.7s, 4ms |
getchar(), putchar() |
0.5s, 3ms |
fread(), putchar() |
0.4s, 3ms |
getchar_unlocked(), putchar_unlocked() |
0.2s, 3ms |
以上是 c005
的題解,謝謝大家。