怎樣寫出清晰易懂的演算法競賽題題解?


清晰易懂,說著容易做著難……

任何類型:

你寫的題解是有受眾的。

你是想作為自己的筆記來寫題解,

還是想寫出來,教授某方面毫無經驗的人,

還是覺得思路巧妙,想和相近水平的人分享?

一般第一種情況,主要要起到關鍵思路點撥和易錯點整理的作用。

這時候,把大概思考過程描述一下,重點總結可以借用到別的題上的思路,還有自己犯下的「無知」的錯誤

第二種情況,也許應該先做好假定:你的讀者至少應該有xx、yy的基礎,沒有學過的請回去學了再來。(你不能讓沒有任何一門編程語言基礎的人來學並查集吧?不然他會搞不懂,要引入這個東西是怎麼回事。)

然後要開始事無巨細地,把這個東西的每個細節講過去,輔以畫圖演示和例題講解(舉例子)就更好了。

第三種情況,要在前2種情況中間做一個平衡,有時甚至要寫得稍微偏向第二種一點。

數論/動態規劃/貪心/構造類:

代碼短短几行,idea可能就是長篇大論了。

寫這種題的題解,不要嫌麻煩,

把你完整的思考過程,像講故事一樣講出去,

把你的推理/整理過程完整、不要跳步,寫出來(什麼「顯然」一定要杜絕,除非是小學數學知識)

最後貼個代碼,只是證明你自己做過這個題,並且過了。

而正確食用這類題解的姿勢是,看懂思路,自己干一份代碼出來。

數據結構類/圖論類/幾何類:

一般除非你的目標是教學/自己做第一發,否則你寫題解的意義,主要是這個思路值得學習。

那簡單:有什麼特殊的組織結構/構圖/計算方法,

如果變化的比較奇怪,解釋一下這麼做的意義。

最後貼代碼。貼的時候變數名字還是稍微花時間整理一下。不要求工程中非常詳盡的變數命名,但要求這個命名至少是大多數人常用的方式。不寫注釋也可以,但要求對一些根本不是重點的基本操作,一目了然,看一眼就知道你在幹嘛。然後對核心的思路這部分,步驟多的就多加一些換行和注釋,步驟少的也可以不加。

經典套路(經典想法)類:

還是按 寫教授某方面毫無經驗的人的題解 的要求來要求自己寫吧(就算只面向自己也一樣)。

當然,如果是這個套路上玩出花樣來,不想重複寫基本套路部分,至少引用一下那個講解詳細的題解吧,這樣都能看懂了。


謝邀。

易懂的題解的關鍵在格式和描述兩個方面。

首先,很多題解都需要數學公式來解釋演算法,這時候請使用 TeX 公式,並且注意公式的規範性(大於(geq)、小於(leq)等符號,向量使用斜粗體(oldsymbol))和美觀程度(多個字母命名函數時使用正體、使用 f(i) 代替 f[i] 和 f_i 等)。我的一篇公式比較多的文章 FFT 學習筆記,和一篇題解 「BZOJ 3156」防禦準備 - 斜率優化 DP。

對於一些難以描述的東西,盡量畫圖解釋。PDF 或者網頁中貼點陣圖不好看,所以我一直用矢量圖。這裡推薦一款矢量做圖軟體 Inkscape,在 Windows 和 Linux 下都很好用(Mac 下可用 Adobe Illustrator 代替)。效果可以看 後綴自動機學習筆記。

幾何上的描述可以用 GeoGebra 畫圖,導出 SVG,效果見 計算幾何學習筆記。

再就是文字描述上,一定要把每一步幹什麼說清楚,最忌諱的就是「把 …… 搞一下」這個句式。用到數據結構時一定要說明維護哪個量,提供什麼操作。必要時分析時間複雜度。圖論(包括網路流)題把每個點代表什麼量,建圖時具體怎麼連邊說清楚。

可以額外說一下自己在做題的時候參考了什麼,思路是怎麼來的,自己一開始是怎麼想錯的。這些可以給讀者額外的啟發。

貼的代碼要規範一些,如果你的代碼風格不是很好(可以參考 Menci"s Code Style for OI),可以找個工具(比如 clang-format)給格式化一下,代碼里必要的地方可以加一些注釋。


作為一個經常看不懂題解的蒟蒻…我真希望題解是用TeX編輯的……當初學斜率優化看dp方程看到吐,想像一下滿屏的圓括弧方括弧?_?


我認為,第一是看你這篇題解的受眾,第二是看你的排版與修飾方式。

如果是新手向題解或者是板子題的題解,建議細寫,而一些較難題的題解只是說清思路和大概的實現方法就可以。這是因為新手刷題較少,對演算法的各部分可能認識不夠,他們需要的是有人可以耐心細緻的跟他們講解,所以寫簡單題的題解要力求把各種細節都解釋到位,尤其要說明白為什麼和怎麼做,不然有可能會達到勸退效果的→_→

(對於給新手看的題解,嚴禁使用下列句式,以前用過的同學請更加要注意:「這個東西用xxx維護一下然後統計一下xxx就可以」 「這個東西做一個xxx然後xxx就可以解決」 「隨便搞搞把xxx算出來就行」,諸如此類句式是可以在較高級題解里說的,但新手很有可能看的一知半解,相比于思路,他們更加需要的是細節)

而能刷到比較難的題的人一般水平相對較高,他們應該擁有良好的代碼能力,這個時候寫題解就可以不那麼詳細了,你只需要說清你的思路和大概的實現,再給一份參考代碼,剩下的讓他們自己去寫就好。

然後是排版和修飾。一篇好的題解不僅要求思路清晰利於理解,還需要很強的可讀性。各段落之間要分清楚,字體字型大小要合適,變色加粗斜體等樣式完全可以按需求適當選用。如果要寫數學公式那自然可以用LaTeX(雖然我不會。。當然我寫的題解里數學公式較少),在對一些重點內容進行講解時,可以適當配圖,配圖要求簡單直觀而不宜過多。

曾經在某OJ上刷題,題解幾乎沒有人排版,代碼看起來非常亂,要是字再多一些那我估計真的是沒有多少人願意讀下去。

並且養成一個良好的代碼風格和經常加註釋的習慣可以讓你的參考代碼看起來更美觀。

(可以去Menci的回答下看看,Menci給推薦了幾款輔助配圖的軟體,我這種鹹魚要給題解上圖肯定就得win+R然後mspaint了。。)


啊啊啊啊啊人生第一次被邀請啊好開心(??????) ?

表示看過的題解還算多……個人覺得大概應該……

1.代碼後面至少帶點注釋,最少是指明這是對應的哪一個步驟

2.寫清楚自己的思路,有些【這個題xx就好了,下面是代碼】

3.思路清晰,代碼裡面的變數最好弄的符合題意

4.如果可以的話寫出這種思路的優點和缺點

5.語言簡潔明了,概括性高而且廢話少

我能想到的大概這樣……?

如果說的不對歡迎評論區指出qaq

來自一名蒟蒻


謝邀。

假如你的程序用到了某方面的演算法,如果對於讀者來說他沒有學過這個,可以附一個相關的鏈接,題解中並不需要指明這類方法的具體原理。

接下來是思路,考慮對於一個掌握相關演算法的讀者來說,他應該以怎樣的想法才能構造出正解中的模型,然後運用呢?

也要保證分析的時間複雜度和空間複雜度可以在接受的範圍內。

對於一些玄學過題的題目,就可以不要發題解了吧。。。(除非你知道為什麼這樣玄學)

必要的時候代碼中要有相關注釋。


推薦閱讀:

如何直接跳出深層遞歸而不是一層一層跳出?
獲得ACM ICPC Regional銀牌是一種什麼樣的體驗?
在acm比賽中擁有 1 or 2 個豬隊友是怎樣的體驗?
為什麼很多程序競賽題目都要求答案對 1e9+7 取模?
搞ACM一定要學習C++嗎?如果是,哪些知識是必要的(只功利地針對ACM,不指做工程項目)?

TAG:演算法 | OI | ACM競賽 | 演算法競賽 |