1. 程式人生 > >套路/錯誤集/黑科技/好寫法

套路/錯誤集/黑科技/好寫法

QAQ因為我寫程式碼太不穩了感覺寫一下錯一下所以在這裡記一記犯過的錯誤(包括解題、打程式和除錯中的問題)

解題

綜合

1.不要以為一個演算法會TLE就不去想,說不定可以優化?說不定可以卡過去?而且一定要記得寫暴力,儘可能少用STL(範圍大的時候……STL太容易被卡掉了)
2.儘可能化簡式子,找規律
3.利用約束,簡化狀態,將思路歸到一起(例如雙路DP規定一邊推導方向,min(x,y)按照xy的大小關係分類推算從而將某個數向外層求和/積符號推)
4.寫程式一定要模組化地寫,如果寫不過嘗試下每個模組去測(特別是資料結構部分),或者如果正解是暴力擴充套件之類的情況,可以從暴力上去一點一點改
5.將4發揮到更加極致的地步,儘可能用一系列read(),solve()等等組成主函式,實際過程在各個函式中寫,分而治之,主函式中僅為呼叫

數論題

1.一定要記得打表,當實在做不出來的時候要找找規律然後再想想怎麼解釋
2.熟記基本函式性質,一看到題目先想想會涉及到那些函式,不要隨便上反演,因為可能有更簡單的做法,推反演的時候也儘可能湊一下基本函式
3.如果這個函式很難求(資料範圍非常大等等),看看關於他的約數的函式怎麼求,然後反演一發
4.反演的時候有時候要記得將一些數論函式展開然後再去列舉約束……
5.如果發現有像[ni][mj]這樣的形式,一般就是可以利用取值最多O(n+m)種的性質來分塊考慮,字首和一波其他剩下的函式然後搞

規劃題

1.先看一眼有什麼樣的序的關係,然後利用這個序去寫約束,看清楚要求什麼樣方向的最大/小
2.一般稍微讀懂題意之後可以稍微分一下類(同樣,還可以按照資料範圍),即動態規劃類、線性規劃類(單純形、網路流、二分圖模型……),然後再繼續考慮優化
3.動態規劃類,包括貪心和其餘的若干DP,貪心分成(正確的、有理有據的)普通貪心,以及亂搞貪心,亂搞貪心稍後再講
4.普通貪心,由於憑直覺

推斷出是區域性最優=全域性最優,那麼我們一般就是進一步推進偏序關係,例如直接排序/取最值,然後通過分析可得到相應的推法
5.DP有很多模型,下面逐一講,這裡先寫通用的
實際上DP和貪心一樣,都是需要一個序才能夠用來推,一定要注意方程推導的順序才能無後效性,不重複、不遺漏

搜尋題

1.一般發現題目很難做,感覺不可維護的規劃類題目就馬上想到搜尋了,而搜尋一般來說在coding和剪枝上非常坑
2.如果要寫搜尋,一定要先看清楚題目給了什麼條件,然後想想怎麼寫好一點,不要一拿到題目就直接開寫
3.首先看看能不能狀壓DP,打搜尋的時候順手加上最優化剪枝,觀察題目性質(隨便貪心)去構造一些看上去挺優的解也行,甚至可以隨機化構造

資料結構題

1.嘗試分析化簡,將題目中所要維護的東西轉成好維護的,或者看看有沒有什麼結論(參見某道區間中取斜率最大的題目,那個一定要是相鄰的)
2.考慮資料結構,能用簡單的就不用複雜的,一般BIT/STL類<線段樹<分塊

計數類題

1.計數題非常的煩,因為一般不可能列舉掉所有情況來計算,必須要數學推公式,然後各種套演算法才能做,一般就是組合數學+遞推(矩陣快速冪優化轉移),有的時候是某種暴力方法結合組合數學優化
2.式子推出來之後先小範圍手算一下對不對再打程式,遞推的時候也想想邊界情況,陣列最好從1開始算(為了邊界更好寫)
3.區間上方案數的問題儘可能想想結論,一般套路可能是離線之後分治,用遞推去搞,也可能是線段樹上一下子記很多個資訊來推。總之一定要先想好沒有區間的版本再去擴充套件,這樣再不濟也能打個暴力……

錯誤集

字串題

1.KMP寫的時候一定要記得初始化,要記得題目要求的座標從1開始還是從0開始
2.儘可能寫熟練的演算法,例如KMP,SA之類的,字尾自動機,AC自動機因為不那麼熟練儘可能比賽時不用

字串題

1.線段樹統計答案的時候最好把子節點再暴力下傳下……

圖論題

1.網路流建反向邊,所以邊數要開兩倍