戰(zhàn):從Markdown到PDF的完整方案與踩坑記錄)
簡(jiǎn)介這份《個(gè)人整理ACM模板》PDF是面向ACM國(guó)際大學(xué)生程序設(shè)計(jì)競(jìng)賽選手及算法學(xué)習(xí)者的實(shí)用模板合集收錄了競(jìng)賽中高頻使用的數(shù)據(jù)結(jié)構(gòu)、數(shù)學(xué)工具與基礎(chǔ)算法旨在幫助讀者快速調(diào)用現(xiàn)成代碼、縮短編碼時(shí)間尤其適合備賽期沖刺或日常刷題時(shí)參考。壓縮包內(nèi)僅含1個(gè)PDF文件整體約2.14MB便于離線查閱和打印。當(dāng)前已有301人學(xué)習(xí)瀏覽實(shí)用性得到了初步驗(yàn)證。內(nèi)容涵蓋常用頭文件組織方式、埃拉托斯特尼篩法、快速冪、大數(shù)加法與階乘模擬、輾轉(zhuǎn)相除法求最大公約數(shù)和最小公倍數(shù)等經(jīng)典實(shí)現(xiàn)每段代碼輔以簡(jiǎn)潔注釋與思路說(shuō)明既可作為比賽時(shí)的“代碼字典”也能作為復(fù)習(xí)數(shù)據(jù)結(jié)構(gòu)和數(shù)論模板的提綱。對(duì)于希望在有限時(shí)間內(nèi)快速定位算法模板、減少重復(fù)造輪子的參賽者來(lái)說(shuō)這份整理周密的PDF能顯著提升解題效率。 如果你已經(jīng)決定要認(rèn)真打幾場(chǎng)算法競(jìng)賽那整理一份屬于自己的 ACM 模板大概率會(huì)在某個(gè)晚上突然變成一件很緊急的事。我見(jiàn)過(guò)不少同學(xué)賽前兩三天才開(kāi)始到處搜模板最后打印出一份幾百頁(yè)的 PDF翻目錄都翻不到 KMP 在哪一頁(yè)也有人把自己的模板整理成了“個(gè)人整理ACM模板.pdf”給自己的比賽生涯省下了大量現(xiàn)場(chǎng)寫(xiě)板子的時(shí)間。這篇文章不打算直接丟給你一份現(xiàn)成模板而是把我自己整理 ACM 模板并沉淀成 PDF 的全過(guò)程拆開(kāi)講清楚模塊怎么規(guī)劃、代碼注釋怎么寫(xiě)、怎么穩(wěn)定地從 Markdown 導(dǎo)出一份排版舒服的中文 PDF以及這一路上踩過(guò)的坑。適合準(zhǔn)備區(qū)域賽、校賽或者單純想把算法體系系統(tǒng)化過(guò)一遍的同學(xué)參考。1. 為什么我也勸你把手里的算法模板收進(jìn)一個(gè) PDF1.1 紙質(zhì)模板在賽場(chǎng)上依然是最可靠的“外掛”ACM 比賽有個(gè)鐵規(guī)矩不能聯(lián)網(wǎng)不能帶自己的代碼文件機(jī)器環(huán)境也是主辦方統(tǒng)一配好的。這意味著你平時(shí)順手就能查的 OI Wiki、GitHub、題解博客在賽場(chǎng)上一律歸零。能帶進(jìn)賽場(chǎng)的除了隊(duì)友的腦子就是打印出來(lái)的紙質(zhì)資料。有人覺(jué)得現(xiàn)在不少比賽允許帶電子版這我沒(méi)法反駁但你可以先想想這幾個(gè)場(chǎng)景機(jī)器上的 IDE 打開(kāi)一個(gè) 5MB 的 PDF 要卡三秒屏幕亮度低 調(diào)代碼調(diào)得眼冒金星比賽后半程裁判提醒電腦快沒(méi)電了。紙質(zhì)模板完全沒(méi)有這些幺蛾子而且翻頁(yè)本身有觸感配合彩色標(biāo)簽紙幾秒鐘就能定位到要找的算法。大部分比賽的規(guī)則里紙質(zhì)資料頁(yè)數(shù)會(huì)有限制常見(jiàn)的是一支隊(duì)伍不超過(guò) 25 頁(yè)。這就帶來(lái)一個(gè)殘酷的事實(shí)不是所有算法都能塞進(jìn)這份 PDF你得做取舍。25 頁(yè)的模板恰恰倒逼你只收藏那些“高頻、短小、能快速上手”的核心代碼。1.2 PDF 在格式層面是各種方案里最省心的我見(jiàn)過(guò)有人用 Markdown 存模板有人用 Word也有人直接開(kāi)個(gè)純文本文件。每種方案都有它的適用場(chǎng)景但如果你最終目標(biāo)是打印 電子檔雙份保存PDF 的優(yōu)勢(shì)非常明顯。格式寫(xiě)起來(lái)打印效果跨設(shè)備一致性適合場(chǎng)景Markdown舒服依賴導(dǎo)出工具一般日常編輯與維護(hù)Word繁瑣穩(wěn)定但代碼塊和公式排版折騰較好非技術(shù)向排版純文本最快幾乎沒(méi)有排版可言好臨時(shí)記錄PDF需借助轉(zhuǎn)換工具固定不變極好最終交付、打印、存檔PDF 的核心優(yōu)勢(shì)是“所見(jiàn)即所得”的一致性你用這個(gè)字體、這個(gè)行距生成出來(lái)隊(duì)友在 Windows 上打開(kāi)裁判在賽場(chǎng)機(jī)器上打開(kāi)看到的頁(yè)面完全一樣不會(huì)因?yàn)橄到y(tǒng)缺字體而錯(cuò)亂。同時(shí) PDF 天然支持書(shū)簽?zāi)夸?、文字檢索和頁(yè)碼電子版在比賽前快速排查某個(gè)模板是否存在時(shí)CtrlF 一按就出來(lái)了。2. 模板內(nèi)容該怎么規(guī)劃模塊化搭建你的算法庫(kù)2.1 第一優(yōu)先級(jí)數(shù)據(jù)結(jié)構(gòu)和基礎(chǔ)算法模板不是越多越好而是越“順手”越好。我自己的整理順序是嚴(yán)格按照使用頻率來(lái)排的第一梯隊(duì)一定是數(shù)據(jù)結(jié)構(gòu)因?yàn)樵谌魏我粓?chǎng)比賽里數(shù)據(jù)結(jié)構(gòu)都是出題人的“寵兒”。我整理的第一層必收清單大致是并查集帶路徑壓縮 按秩合并處理集合合并與查詢問(wèn)題。樹(shù)狀數(shù)組單點(diǎn)修改、區(qū)間查詢代碼量小常數(shù)也小。線段樹(shù)區(qū)間加、區(qū)間求和、區(qū)間最值懶標(biāo)記是必會(huì)的最基礎(chǔ)寫(xiě)法。KMP單模式串匹配next 數(shù)組的求法必須背熟。Trie 字典樹(shù)處理前綴匹配和異或相關(guān)問(wèn)題時(shí)非常常用。哈希表手寫(xiě)一個(gè)簡(jiǎn)單的哈希避免賽后發(fā)現(xiàn) STL 被卡常數(shù)。以并查集為例模板里我會(huì)放這樣的代碼// 并查集merge(x, y) 合并find(x) 查詢根 // 復(fù)雜度均攤 O(alpha(n)) // 注意使用前需要初始化 fa[i] i int fa[MAXN], rk[MAXN]; int find(int x) { return fa[x] x ? x : fa[x] find(fa[x]); } void merge(int x, int y) { x find(x); y find(y); if (x y) return; if (rk[x] rk[y]) swap(x, y); fa[y] x; if (rk[x] rk[y]) rk[x]; }這類代碼短、無(wú)歧義、幾乎每年都能用到屬于模板里的“壓艙石”。2.2 按“出題概率 × 代碼長(zhǎng)度”篩選圖論、數(shù)論、DP、計(jì)算幾何第二層是按專題往里塞內(nèi)容我給自己定的篩選公式很簡(jiǎn)單一句話題解打成三個(gè)字——值不值。一個(gè)算法值不值得占模板的一頁(yè)就看它在賽場(chǎng)上出現(xiàn)的頻率夠不夠高以及代碼長(zhǎng)度是不是在“現(xiàn)場(chǎng)能默寫(xiě)”和“必須看模板”之間。以圖論為例必收的是堆優(yōu)化 Dijkstra單源最短路、Kruskal最小生成樹(shù)、拓?fù)渑判颉arjan強(qiáng)連通分量/縮點(diǎn)。SPFA 我建議不要放現(xiàn)在的出題人太會(huì)構(gòu)造數(shù)據(jù)卡它了。網(wǎng)絡(luò)流 Dinic 我直到大二才把它放進(jìn)模板因?yàn)樗m然長(zhǎng)得像模板題專屬但在一些難題里做建模中轉(zhuǎn)時(shí)確實(shí)能救命。數(shù)論這塊擴(kuò)展歐幾里得、快速冪、線性篩、逆元、組合數(shù)取模是必收項(xiàng)剩下的 Lucas、歐拉函數(shù)、莫比烏斯反演看個(gè)人精力。動(dòng)態(tài)規(guī)劃不是“模板重災(zāi)區(qū)”因?yàn)闋顟B(tài)轉(zhuǎn)移方程幾乎無(wú)法模板化我會(huì)把 0-1 背包、完全背包、區(qū)間 DP、LIS/LCS、數(shù)位 DP、狀壓 DP 的轉(zhuǎn)移框架各寫(xiě)一個(gè)“最小可運(yùn)行版本”用來(lái)提醒自己初始化邊界和循環(huán)順序。計(jì)算幾何是很多人容易忽略的板塊但凸包、最近點(diǎn)對(duì)、向量叉積判斷點(diǎn)與線段位置這些在區(qū)域賽里出現(xiàn)的頻率并不低。這類代碼一般不長(zhǎng)但細(xì)節(jié)多屬于“明明會(huì)寫(xiě)現(xiàn)場(chǎng)一緊張就寫(xiě)錯(cuò)”的類型放進(jìn) PDF 價(jià)值極高。另外提醒一句網(wǎng)上確實(shí)有大量整理好的 ACM 模板 PDF、Hot 100 題解 PDF 之類你可以參考它們的目錄結(jié)構(gòu)但千萬(wàn)不要直接拿別人的來(lái)打印。整理模板的過(guò)程本身就是在梳理你的知識(shí)盲區(qū)別人的模板再好到了你手上你也很難在賽場(chǎng)上一眼找到自己需要的那一段。2.3 明確“不收錄”清單控制模板總量25 頁(yè)的容量是稀缺資源所以我給自己定了三條“不收錄”原則第一超過(guò)一頁(yè)才能寫(xiě)完的算法要么拆要么砍。拆的意思是只保留核心部分把邊界處理寫(xiě)成注釋砍的意思是直接移除。我見(jiàn)過(guò)有人把 Splay 的完整實(shí)現(xiàn)塞進(jìn)模板整整兩頁(yè)半說(shuō)實(shí)話真到賽場(chǎng)上你根本來(lái)不及調(diào)那么長(zhǎng)的代碼。第二在 30 秒內(nèi)找不到位置的算法不配進(jìn)模板。如果一個(gè)算法在你的目錄里藏在三級(jí)標(biāo)題的某個(gè)角落里翻了兩頁(yè)還沒(méi)翻到那它和沒(méi)帶沒(méi)有區(qū)別。為了提升查找效率我的目錄結(jié)構(gòu)固定為“數(shù)據(jù)結(jié)構(gòu) / 圖論 / 數(shù)論 / DP / 計(jì)算幾何 / 雜項(xiàng)”每個(gè)分類下最多 6 個(gè)模板。第三原理沒(méi)吃透的算法不要放。有些選手會(huì)把一些自己沒(méi)完全理解的高級(jí)數(shù)據(jù)結(jié)構(gòu)硬塞進(jìn)模板結(jié)果賽場(chǎng)上抄下來(lái)之后一改就崩反而浪費(fèi)大量時(shí)間。模板應(yīng)該是你“腦子已經(jīng)會(huì)了手需要提醒一下”的東西而不是你的“自動(dòng)駕駛儀”。3. 模板代碼的編寫(xiě)規(guī)范讓打印出來(lái)的代碼一樣能看懂3.1 統(tǒng)一風(fēng)格與變量命名模板代碼和普通做題代碼的最大區(qū)別是你是在“學(xué)習(xí)狀態(tài)下”寫(xiě)它在“緊張狀態(tài)下”用它。所以代碼風(fēng)格必須統(tǒng)一到“閉著眼睛都能改”的程度。我的習(xí)慣是所有模板統(tǒng)一用 4 空格縮進(jìn)大括號(hào)換行風(fēng)格全篇保持一致。變量名盡量短但可讀cnt、tot、ans這種都可以但不要用a、b、c到底。數(shù)組大小統(tǒng)一用MAXN代替具體數(shù)字并在注釋中明確標(biāo)注“若 N 范圍超過(guò) 1e6請(qǐng)修改”。另外每個(gè)模板文件里我都會(huì)自己維護(hù)一份“通用頭”——包括快讀函數(shù)。比賽里輸入數(shù)據(jù)可能很大cin就算解綁了同步有時(shí)候也不夠穩(wěn)一份帶getchar的快讀模板屬于剛需。3.2 注釋寫(xiě)“怎么用”不寫(xiě)“為什么”這一點(diǎn)我特別想強(qiáng)調(diào)。很多人在整理模板時(shí)會(huì)把算法原理長(zhǎng)篇大論地寫(xiě)在代碼上面什么“本算法基于分治思想每次將區(qū)間一分為二……”這類話在賽場(chǎng)上一點(diǎn)用都沒(méi)有。模板注釋的正確寫(xiě)法是告訴未來(lái)的自己這個(gè)函數(shù)接收什么參數(shù)、返回什么結(jié)果、復(fù)雜度是多少、有哪些坑。// 樹(shù)狀數(shù)組單點(diǎn) add(pos, val)區(qū)間 query(l, r) // 復(fù)雜度add 和 query 均為 O(log n) // 注意需要先 init(n) 設(shè)置大小下標(biāo)從 1 開(kāi)始 int tr[MAXN], n; void init(int _n) { n _n; memset(tr, 0, sizeof(tr)); } void add(int pos, int val) { for (; pos n; pos pos -pos) tr[pos] val; } int sum(int pos) { int res 0; for (; pos 0; pos - pos -pos) res tr[pos]; return res; } int query(int l, int r) { return sum(r) - sum(l - 1); }至于這個(gè)算法為什么對(duì)、數(shù)學(xué)證明是什么那是你平時(shí)訓(xùn)練該解決的事不應(yīng)該出現(xiàn)在模板里。模板不是教材是“提詞器”。3.3 每個(gè)模板塊拆成三段式結(jié)構(gòu)我自己的每個(gè)模板塊都固定成三段式第一段功能標(biāo)題 復(fù)雜度標(biāo)題里直接寫(xiě)出算法名字比如“線段樹(shù)——區(qū)間加 區(qū)間求和懶標(biāo)記”。第二段核心代碼。這段代碼必須是可直接運(yùn)行、可編譯通過(guò)的。我會(huì)在每次生成 PDF 前用一個(gè)統(tǒng)一的測(cè)試文件把所有模板代碼編譯一遍。第三段調(diào)用示例。寫(xiě)一個(gè)極簡(jiǎn)的main函數(shù)里面只有幾行輸入和調(diào)用方便我在賽場(chǎng)上快速回憶起“這函數(shù)到底該按什么順序調(diào)”。之所以強(qiáng)調(diào)第三段是因?yàn)槲页缘竭^(guò)不少苦頭。有一年區(qū)域賽我用了自己模板里的 LIS 變種結(jié)果因?yàn)闆](méi)寫(xiě)調(diào)用示例那個(gè)參數(shù)順序我看了整整半分鐘才反應(yīng)過(guò)來(lái)是“先傳數(shù)組名再傳長(zhǎng)度”。半分鐘在賽場(chǎng)上屬于相當(dāng)昂貴的代價(jià)。4. 從 Markdown 到 PDF一套貼近實(shí)戰(zhàn)的生成流程4.1 工具鏈選擇與理由工具鏈我試過(guò)好幾套純 Typora 導(dǎo)出 PDF、VS Code 插件 Markdown PDF、在線轉(zhuǎn)換網(wǎng)站最后穩(wěn)定在“Markdown Pandoc XeLaTeX”這套方案。為什么不用 Typora 直接導(dǎo)出因?yàn)樗叩囊彩莾?nèi)置渲染引擎對(duì)長(zhǎng)文檔的分頁(yè)控制很弱代碼塊跨頁(yè)時(shí)經(jīng)常出現(xiàn)很丑的斷行。為什么不用在線轉(zhuǎn)換工具因?yàn)?ACM 模板涉及大量代碼塊、縮進(jìn)、中英文混排在線工具導(dǎo)出的格式往往不可控而且你的代碼內(nèi)容放在別人服務(wù)器上總歸不太安心。Pandoc 的路線是先用 Markdown 寫(xiě)內(nèi)容再用 Pandoc 轉(zhuǎn)成 LaTeX 中間文件最后由 XeLaTeX 引擎渲染 PDF。這條路的好處是每個(gè)環(huán)節(jié)都在你本地完成可復(fù)現(xiàn)且一旦調(diào)試好參數(shù)以后每次導(dǎo)出都是同一個(gè)漂亮結(jié)果。4.2 親測(cè)可用的 Pandoc 命令與參數(shù)詳解我目前在 Linux 環(huán)境下用的命令大概是這樣的pandoc ACM_template.md -o ACM_template.pdf \ --pdf-enginexelatex \ -V CJKmainfontNoto Sans CJK SC \ -V mainfontNoto Sans Mono CJK SC \ -V geometry:margin2cm \ --toc \ --highlight-styletango \ -V colorlinkstrue這幾個(gè)參數(shù)逐個(gè)說(shuō)--pdf-enginexelatex指定用 XeLaTeX 作為 PDF 引擎它原生支持 Unicode中文字體處理比舊版 pdflatex 省心得多。-V CJKmainfontNoto Sans CJK SC設(shè)置中文字體。如果你的系統(tǒng)沒(méi)有這個(gè)字體可以用fc-list :langzh查看可用中文字體然后再換名字。-V mainfontNoto Sans Mono CJK SC設(shè)置西文和等寬字體。代碼塊會(huì)大量使用等寬字體這一項(xiàng)直接影響代碼顯示效果。-V geometry:margin2cm設(shè)置頁(yè)邊距。2cm 是我實(shí)測(cè)下來(lái)比較舒服的寬度既能保證一頁(yè)放足夠多內(nèi)容又不會(huì)顯得太擠。如果頁(yè)數(shù)緊張可以縮到 1.8cm。--toc自動(dòng)生成目錄。配合 Pandoc 的分頁(yè)邏輯會(huì)出現(xiàn)在文檔開(kāi)頭。--highlight-styletango設(shè)置代碼高亮主題。tango 是打印友好的淺色主題避免代碼塊變成黑底白字浪費(fèi)墨水又傷眼。-V colorlinkstrue讓 PDF 里的超鏈接顯示為彩色。如果你要打印建議后面改成-V colorlinksfalse否則打印出來(lái)一片藍(lán)。如果你在 Windows 上建議搭配 TeX Live 或者 MiKTeX同時(shí)用-V CJKmainfontMicrosoft YaHei這類系統(tǒng)中文字體名。4.3 目錄、分頁(yè)與代碼高亮的細(xì)節(jié)處理Pandoc 默認(rèn)會(huì)把一級(jí)標(biāo)題當(dāng)成章二級(jí)標(biāo)題當(dāng)成節(jié)生成書(shū)簽這對(duì) ACM 模板來(lái)說(shuō)其實(shí)夠用。但有一個(gè)問(wèn)題需要手動(dòng)處理分頁(yè)。你肯定不希望“并查集”和“樹(shù)狀數(shù)組”這兩個(gè)毫無(wú)關(guān)系的模板擠在同一頁(yè)上。解決辦法是在 Markdown 源文件里每個(gè)二級(jí)標(biāo)題前手動(dòng)插入一個(gè) LaTeX 換頁(yè)指令\newpage ## 2. 圖論P(yáng)andoc 默認(rèn)是支持 raw_tex 擴(kuò)展的也就是說(shuō)這個(gè)\newpage會(huì)原樣傳給 LaTeX 引擎最終效果就是在“圖論”這一節(jié)之前強(qiáng)制分頁(yè)。注意這個(gè)指令在 Typora 預(yù)覽里不會(huì)變成真正的分頁(yè)但你不用管等導(dǎo)出 PDF 時(shí)它就會(huì)生效。代碼高亮還有一個(gè)隱藏問(wèn)題Pandoc 的默認(rèn)高亮主題在打印時(shí)會(huì)帶背景色如果整段代碼底色是灰色打印頁(yè)數(shù)一多墨水消耗會(huì)很夸張。我的做法是除了--highlight-styletango還會(huì)在生成的 LaTeX 文件里微調(diào)代碼字號(hào)把列表環(huán)境里的字體從默認(rèn)的\small改成\footnotesize這樣同樣的內(nèi)容能壓掉不少行數(shù)。如果你只是想快速導(dǎo)出一版看看效果不追求最終質(zhì)量直接用 Typora 的“導(dǎo)出 PDF”按鈕也可以。但正式比賽前我還是建議走一遍 Pandoc 路線因?yàn)樗o了你完全可控的分頁(yè)和目錄。5. 常見(jiàn)問(wèn)題與排查技巧實(shí)錄5.1 中文亂碼與字體問(wèn)題這是我最開(kāi)始折騰最久的一個(gè)問(wèn)題。現(xiàn)象是PDF 生成成功但所有中文都變成了黑色方塊或者直接消失。原因幾乎可以確定是 XeLaTeX 找不到中文字體或者沒(méi)有正確設(shè)置CJKmainfont。解決步驟很固定在終端執(zhí)行fc-list :langzh查看系統(tǒng)裝了哪些中文字體??摧敵隼镉袥](méi)有Noto Sans CJK SC、WenQuanYi Micro Hei、Microsoft YaHei這類字體。把查到的一個(gè)字體名字填到-V CJKmainfont字體名注意字體名中間有空格就必須加引號(hào)。如果你已經(jīng)設(shè)置了字體還是亂碼大概率是 Pandoc 版本太老。建議把 Pandoc 升級(jí)到 2.x 以上XeLaTeX 也要保證是 TeX Live 2019 之后的版本舊版對(duì)中文支持的細(xì)節(jié)確實(shí)差很多。5.2 代碼跨頁(yè)斷行與排版崩壞長(zhǎng)代碼塊和分頁(yè)機(jī)制的沖突是所有模板里最頭疼的一件事。常見(jiàn)情況是一個(gè)線段樹(shù)模板長(zhǎng)度超過(guò)一頁(yè)P(yáng)andoc 直接把代碼硬生生從中間切斷下一頁(yè)從后半截開(kāi)始看起來(lái)非常難受。我的應(yīng)對(duì)思路有兩個(gè)方向。第一個(gè)方向是“人事分離”把過(guò)長(zhǎng)的代碼拆成“核心邏輯”和“完整實(shí)現(xiàn)”兩截。核心邏輯只保留最重要的 update 和 query 函數(shù)完整實(shí)現(xiàn)可以作為附錄放在分類末尾。賽場(chǎng)上的需求通常是“回憶一下怎么改”不是“從頭抄一遍”所以核心邏輯那幾行往往比完整代碼更有用。第二個(gè)方向是技術(shù)手段在 Pandoc 命令里給 listings 環(huán)境設(shè)置自動(dòng)換行和斷行。我實(shí)測(cè)可以這樣加參數(shù)-V listings -V listings-disable-line-numbers然后在 Markdown 里用listing環(huán)境替代普通代碼塊不過(guò)這套玩法對(duì) Markdown 的侵入性比較大適合你已經(jīng)很熟悉 LaTeX 的情況。如果你的需求只是“模板打印出來(lái)能看”前一個(gè)方向足夠。5.3 PDF 體積、打印效果與閱讀體驗(yàn)PDF 文件動(dòng)不動(dòng)幾十 MB通常是嵌入了大量字體子集導(dǎo)致的。模板這種純文字 PDF 其實(shí)體積不會(huì)太大如果看到異常膨脹檢查一下 Markdown 源文件里有沒(méi)有不小心塞進(jìn)去的大圖片。打印層面有幾個(gè)實(shí)測(cè)建議問(wèn)題建議鏈接顏色在黑白打印下變灰塊導(dǎo)出時(shí)設(shè)置-V colorlinksfalse雙面打印后內(nèi)容壓到裝訂線在 geometry 參數(shù)里加bindingoffset0.5cm代碼背景色太深用--highlight-styletango或breezedark這類淺色主題頁(yè)碼看不清在 LaTeX 模板或頁(yè)腳設(shè)置里加大頁(yè)數(shù)字號(hào)另外我強(qiáng)烈建議在最終打印前先打印一頁(yè)測(cè)試頁(yè)看看字體、行距、代碼縮進(jìn)到底什么效果。你整理這個(gè) PDF 花的力氣最后都要靠打印效果來(lái)兌現(xiàn)。6. 模板的迭代維護(hù)與賽場(chǎng)使用小技巧6.1 訓(xùn)練賽后標(biāo)準(zhǔn)化更新流程模板不是整理一次就完事的東西它應(yīng)該跟著你的水平一起漲。我給自己定了一個(gè)標(biāo)準(zhǔn)流程每次訓(xùn)練賽結(jié)束我都會(huì)在賽后補(bǔ)題時(shí)問(wèn)自己一個(gè)問(wèn)題這場(chǎng)比賽里有沒(méi)有一個(gè)算法是我“會(huì)但寫(xiě)得很慢”或者“明明可以做出來(lái)卻因?yàn)榇a不熟浪費(fèi)了太多時(shí)間”的如果有就在賽后的統(tǒng)一維護(hù)時(shí)間里把這個(gè)算法的模板優(yōu)化一遍。優(yōu)化包括精簡(jiǎn)代碼、補(bǔ)注釋、重新編譯驗(yàn)證然后同步更新到 Git 倉(cāng)庫(kù)再重新導(dǎo)出 PDF。這套流程一周一次平均每周花 40 分鐘。別小看這一點(diǎn)點(diǎn)更新我有一版線段樹(shù)模板就是這樣從最初的 80 行“大頭娃娃”逐步瘦身到 60 行的而賽場(chǎng)上的效率提升是立竿見(jiàn)影的。6.2 打印、收納與現(xiàn)場(chǎng)快速查找的經(jīng)驗(yàn)關(guān)于紙質(zhì)模板的現(xiàn)場(chǎng)使用有三件事我想按重要性從高到低排一下序。第一件也是最重要的一件給每個(gè)大分類貼彩色標(biāo)簽。數(shù)據(jù)結(jié)構(gòu)用紅色標(biāo)簽圖論用藍(lán)色數(shù)論用綠色DP 用黃色計(jì)算幾何用橙色。這樣你在賽場(chǎng)上翻模板瞄一眼顏色就能定位到分類再翻幾下就能找到具體算法比看目錄還要快。我見(jiàn)過(guò)太多人辛辛苦苦做了 PDF打印出來(lái)卻是一沓白紙黑字賽場(chǎng)上翻模板翻了五分鐘心態(tài)直接爆炸。第二件目錄頁(yè)打印在封面背面。目錄是檢索的第一入口一定要放在一眼能看到的位置。而且目錄上的頁(yè)碼要跟 PDF 導(dǎo)出的頁(yè)碼一致所以每次更新后要重新打印不能拿舊目錄去對(duì)著新版模板。第三件賽前做一次“20 分鐘手抄模板”測(cè)試。具體做法是隨機(jī)抽出模板里的 3 個(gè)算法打印在試卷紙上20 分鐘內(nèi)不看任何資料憑記憶手寫(xiě)出來(lái)。如果哪一步卡住了說(shuō)明那個(gè)模板的注釋還不夠清晰或者代碼邏輯你還是沒(méi)吃透需要回爐重做。這個(gè)測(cè)試聽(tīng)起來(lái)有點(diǎn)變態(tài)但實(shí)測(cè)非常能發(fā)現(xiàn)模板的“偽熟練”問(wèn)題。說(shuō)回“個(gè)人整理ACM模板.pdf”這件事本身。整理模板真正磨人的不是寫(xiě)代碼的那一下子而是你發(fā)現(xiàn)同一段 KMP 你已經(jīng)在不同地方抄過(guò)第三遍了。我的習(xí)慣是每次看到別人代碼里有更簡(jiǎn)潔的寫(xiě)法、更少 bug 的邊界處理就當(dāng)場(chǎng)替換掉自己模板里的對(duì)應(yīng)段落。這個(gè)習(xí)慣讓我少打了很多無(wú)意義的字也讓我的模板在一次次比賽里變得越來(lái)越“聽(tīng)話”。最后一個(gè)小小的建議PDF 生成之后一定要自己打印出來(lái)在睡前或者通勤路上多翻幾遍。只有被反復(fù)翻過(guò)的模板比賽時(shí)才真正長(zhǎng)在你手上。本文還有配套的精品資源點(diǎn)擊獲取