編程環境:
比賽時使用的編譯器是Dev-C++,並沒有Visual Studio這樣的外掛,所以最好在比賽前使用一下Dev
Dev的默認編譯環境與vs不同,需要手動設置Dev的C++標準,否則無法使用一些C++11的新特性,比如auto關鍵字【設置教程】
Dev的標準庫有一定殘缺,部分函數例如to_string()是沒有的,需要使用一些C++14/17的特性的時候,不要指望用Dev能運行成功
Dev的調試功能比較難用,比較簡單的辦法是輸出變量值來調試
題型分析:
L1:
L1有幾道送分的題目,其他大多是來考察參賽者的邏輯思考能力以及對程序邏輯的掌控能力,L1的題目比較簡單,出錯往往是因爲讀題不仔細,儘量認真讀題,輕敵出錯的話,就有點得不償失,爭取以最快的時間完成L1的題目。
L2:
涉及到一些數據結構算法,結構主要是棧,樹(搜索樹),隊列,並差集等,而算法主要是考察一些搜索算法(深度優先搜索算法,廣度優先搜索算法),最短路徑算法(Dijkstra算法,Floyd算法),去年(2019)考了的隊列以及並差集算法。
L3:
L3的題型與L2類似,但難度稍大,另外會有一些跟實際開發相關的題目以及一些幾何題目,近年的比賽還出現了一種比較特殊的題型,即答案不唯一,使用特殊裁判程序進行判定的題目(L3-012水果忍者,L3-024 Oriol和David),這類題目難度較大,需要理解題意,並且分析出題目的判定機制,纔有解題思路。
時間優化:(寫好的代碼有測試點運行超時,可以暫時放下,不要繼續浪費時間)
1、如果出現運行超時第一時間思考是否是因爲非法輸入導致死循環。
2、儘量使用scanf,printf,而不使用cin,cout(C++的IO存在緩存(可取消));
3、不要重複創建臨時變量(創建一次,後面賦值);
for (int i = 0; i < 100; i++) { //錯誤用法
int t;
cin >> t;
}
int t;
for (int i = 0; i < 100; i++) { //正確
cin >> t;
}
4、使用引用訪問容器中的元素(遍歷,排序);
vector<int> vc{ 0,1,2,3 };
for (int i : vc) //錯誤
cout << i;
for (int& i : vc) //正確
cout << i;
5、使用unordered_map,unordered_set替換map,set可以提升效率,注意修改時同時修改頭文件;
6、一般圖論問題都可以用深搜,但效率較低,容易超時,單源最短路徑——Dijkstra,連通度、集合圖——並查集;
7、圖論問題,當數據量十分龐大(一般超過10^3個結點),使用map做鄰接表效率很低,所以鄰接表能用數組儘量用數組;
8、爲了實現排序功能,儘量使用sort對數組排序,而不要依賴與map和set的自動排序(map,set結構龐大);
9、一般遞歸算法都比較慢,深搜可以通過剪枝優化,並查集可以進行路徑壓縮提升效率。
10、當數組是有序的,可以考慮使用折半查找,<algorithm>庫中提供了binary_search()函數
比賽技巧:
1、由於PAT的題目測試數據較少,所以有些題目可以適當投機取巧。
2、儘量一次寫對,不要回頭找bug。
3、爲了方便函數調用,可以都用全局變量,但你得記住,這是個(壞習慣)
4、不確定數據多少的情況,不一定非要用動態數組,可以直接根據題目給的數據範圍定義一個較大的數組(大小應大於題目所給的範圍),一般情況下不會出現內存超限(數組大小別超過10^8,二維數組不能超過array[10000][10000])(壞習慣)
5、一般情況下答案錯誤很可能是漏了題目的關鍵信息。
6、格式錯誤是因爲排版跟題目要求不同,可能會多空格或空行
7、段錯誤是由於非法訪問纔會導致的,所以一般情況下,出現段錯誤,是因爲數組訪問越界。
8、題目給的測試樣例,一般是跟前面的測試點相對應的,最少得到這些測試點的分,其他的,適當取捨。
9、涉及到除法,需要考慮除數不能爲0,一般會有一個測試點。
10、圖論問題用深搜可以得到大部分的分。
11、選取適當的結構(容器)可以讓思路更清晰。
12、熟悉編譯器的調試功能可以更快的找出bug。
必備知識:
數據結構與算法:(結構、算法來源於生活,理解、不要記模板)
1、樹:二叉樹的遍歷方式,平衡二叉樹的建樹過程,根據兩種遍歷來建樹
2、圖:深搜,廣(層)搜,並查集(推薦博客)。
3、堆:堆結構,建堆過程(堆排序)。
4、鏈表:根據結點連接鏈表(一般通過結構體進行模擬)。
5、排序:熟悉快排和歸併排序的排序過程
常用庫、函數(黑科技):
容器:
字符串處理:
知識點 | 說明 | 推薦博客 |
string容器 | 封裝了一些對字符串的常用操作 | 鏈接 |
regex正則表達式 | 使用正則表達式來替換、查找字符串 | 鏈接 |
stirngstream字符串IO類 | 使用字符串來進行IO操作 | 鏈接 |
常用字符處理函數 |
isdigit(char ch) |
lambda表達式:
自定義排序:
類型轉換:
數值邊界:
數學函數:
auto關鍵字:根據賦值自動推導數據類型
堆:
常用功能函數:
查找
計數
倒序
2、sort函數排序,自定義結構體比較方式(可重載<,或重載())。
3、STL標準庫 list , vector,queue,stack,map,set 的各種操作。
4、類型轉換:(可以通過sscanf,sprintf轉換)
char->int: -'0' int->char: +'0';
string->int:int stoi(string str) int->string: string to_string(int i) 同理有stof,atoi(char*->int)
5、類型判斷:(都可以自己寫)
比如 isdigit()判斷爲數字,反正你只要輸入is,編譯器後面會提示你有些什麼函數,你翻譯一下就知道功能了。
6、數組(容器)倒敘:
(1)倒敘函數:void reverse(typename begin,typename end);
(2)利用反向迭代器倒敘(構造 new string),以字符串str爲例:
string s=string(str.rbegin(),str.rend()) or s.assign(str.rbegin(),str.rend());
7、auto關鍵字——(是不是突然知道了python不需用數據類型的祕密?=.=)
8、find函數:
string str; // string類成員函數:未找到返回string::npos
if (str.find("substr") != string::npos);
//do something
set<int> st;
if (st.find(0) != st.end()); //set、map成員函數:未找到返回尾迭代器
//do something
vector<int> vc;
if(find(vc.begin(), vc.end(), 0)!=vc.end()); //序列式容器可以通過algorithm庫中find函數查找,未找到返回尾迭代器
//do something
9、find_if、count、count_if,transform....(不常用、可以自己實現)