跳转至

學習路線

提示

本文章正在編輯討論中,歡迎補充更進一步的學習路線或在評論區提出你的想法!

本文將會介紹算法競賽的學習路線。

該學習路線既是新手學習算法競賽知識的指南,也是一份複習清單。

1 C++ 語言基礎

先從 C++ 語法學起,一步一步來。

1.1 Hello, World!

以一句 Hello, World!,開始算法競賽之旅吧!

同時瞭解一下 C++ 的源程序的大致框架是什麼樣子的。

1.2 變量與運算

計算機出現的最初目的就是計算。因此我們先學習如何完成一些簡單的運算任務吧。

1.3 流程控制

1.3.1 分支結構

有的時候,我們需要在不同的條件下,選擇執行不同的語句,這時候我們就需要藉助分支語句。

分支語句包括下面幾種:

  • if 語句
  • if-else 語句
  • if-elif-else 語句
  • switch 語句

1.3.2 循環結構

將若干條語句重複執行多次,就需要用到循環語句。

循環語句包括下面幾種:

  • for 語句
  • while 語句
  • do-while 語句

1.4 數組與結構體

數組用於存儲大量相同類型的數據。而結構體則可以將若干變量捆綁起來。

1.5 函數與遞歸

使用函數來讓程序變得模塊化,降低實現成本。

遞歸則是新手入門的一道坎,「自己調用自己」聽起來並不是那麼容易理解,不過仔細深究根本,就會發現「自己調用自己」和「自己調用別人」並沒有本質差別。

2 CSP-J 入門級

2.1 枚舉與模擬

從現在開始,你已經會使用 C++ 語言完成一些簡單的任務了,但是這遠遠不夠。

為了做對一些簡單的題目,你需要學會通過枚舉或模擬腦海中的邏輯,來實現代碼。這看起來並不是很高效,但有的時候很管用。

2.2 遞歸與分治

遞歸是指函數定義中不斷調用自己的方法;而分治則是不斷將這一個問題分解為若干子問題,求解後合併的操作。

2.3 字符串

在做信息學題目時,經常會碰到的一個數據類型就是字符串,你需要學習一些用於操作字符串的 STL 函數。當然,模擬也是解決字符串問題的好方法。

2.4 排序

當你獲得了一組數據時,如何將他們從無序變成有序也是個很重要的問題。在你沒有思路的時候,不妨考慮一下將數組排個序吧。這也是接下來的很多算法的基礎。

排序的方法有點多,但理解後記住它們並不難。

NOI 大綱中入門級只要求學習選擇、冒泡、插入排序,共三個排序算法,但是其餘的難度也並不大,且初賽中可能涉及,故一併列出。

2.5 二分與倍增

二分查找,本質上是運用分治的思想,不斷減少查找範圍的大小,直至找到答案。但是需要注意,這個查找方式必須應用在有序的數據結構中。

而倍增則不同,它是不斷翻倍,以把線性範疇內的處理轉化為對數級,大大優化時間複雜度。(這個知識點需要一點數學基礎,暫時跳過也問題不大)

2.6 搜索

在入門組,搜索的題目常常會在迷宮類題目中出現,一般會有地圖類的數據;此外,搜索也十分常用於高效地枚舉構造合法解的情況,亦可用於騙分。

2.6.1 深度優先搜索(DFS)

深度優先搜索指利用遞歸函數方便地實現暴力枚舉的算法,與圖論中的 DFS 算法有一定相似之處,但並不完全相同。

2.6.2 廣度優先搜索(BFS)

將每一個狀態設計為圖中的一個點,可以展開地毯式搜索。

2.6.3 搜索優化

很多題目都可以用 DFS 來解決,而這個算法的複雜度顯然是無法通過的。因此,需要一些優化使它跑得更快。這樣的優化能夠減少不可能成功的嘗試,稱為「剪枝」。BFS 相關的優化就要更加靈活了,但是基本思路和這裏是一樣的。

2.7 數據結構入門

2.7.1 線性數據結構

數組,鏈表,隊列,棧,都是線性結構。巧用這些結構可以做出不少方便的事情。

2.7.2 複雜數據結構

2.8 動態規劃入門

動態規劃(Dynamic Programming, DP)是一種通過把原問題分解為相對簡單的子問題的方式求解複雜問題的方法。

由於動態規劃並不是某種具體的算法,而是一種解決特定問題的方法,因此它會出現在各式各樣的數據結構中,與之相關的題目種類也更為繁雜。

2.8.1 揹包問題

即給出一個有限制容量的揹包,選擇放入若干有容量和價值的物品,求解如何放置能使得價值總和最大。這是阻擋很多 OIer 的第一道坎,從這裏開始,算法就有些難以理解。

2.8.2 線性動態規劃

在動態規劃中,最難的部分之一就是設計狀態,需要用到構造相關技巧。當你寫出了狀態和狀態轉移方程之後,完成一道動態規劃的題目就不難了。

記憶化搜索是一種通過記錄已經遍歷過的狀態的信息,從而避免對同一狀態重複遍歷的搜索實現方式。有的題目也可以使用記憶化搜索來降低思維難度。

因為記憶化搜索確保了每個狀態只訪問一次,它也是一種常見的動態規劃實現方式。

2.8.3 複雜動態規劃

區間類動態規劃是線性動態規劃的擴展,它在分階段地劃分問題時,與階段中元素出現的順序和由前一階段的哪些元素合併而來有很大的關係。

2.9 數學

2.9.1 高精度算法

就算是 long long(或 int64)還不夠怎麼辦?用高精度算法。本質上就是模擬了四則運算。

2.9.2 進制轉換

在計算機中,除了二進制,比較常用的還有八進制和十六進制。有的時候學會運用正確的進制對解題也有很大幫助。

2.9.3 位運算

位運算就是基於整數的二進制表示進行的運算。由於計算機內部就是以二進制來存儲數據,位運算是相當快的。

基本的位運算共 6 種,分別為按位與、按位或、按位異或、按位取反、左移和右移。

2.9.4 數論

2.9.5 組合計數


至此,你就學習完了入門組範疇內的所有算法,但是想要掌握它們,你需要繼續進行足夠數量的刷題,以鞏固你所學到的知識點。