一、總學習原則:
1.使用有道詞典記錄單詞,並提高英語閱讀能力,增加詞彙量。
2.《算法競賽入門經典》指導下,先按照學習內容做題,再自由選題。
3.做好做題的筆記,記錄技巧,錯誤原因,及新知識點總結。
4.實現優先使用C語言,設計高級算法時考慮使用C++。輔助書籍:C語言相關幾個書、《算法導論》
二、AOAPC I 題目及筆記:
Volume 0:
494:
知識點:
使用ctype.h文件進行字符分類和字符轉換。
C語言下單行處理:(gets在gcc下編譯會彈出warning,而fget能夠防止緩存區溢出)
char line[1024];
while(gets(line)) ...
技巧:深刻理解題目的對一些術語的定義,按照定義寫算法。
414:
細節:gets遇到第一個換行符就結束,因此如果讀取時緩衝區第一個字符就是換行符的話將什麼都讀不到,注意緩衝區可能留有上一行的換行符或輸入中遇到只有一個換行符的行。
總結:
主要考察scanf\printf\gets\getchar(<string.h>)使用,這部分相當基礎。
技巧:輸出時若想檢測空白字符是否輸出正確(特別時空格),在調式時可以暫時使用別的可視字符替代。
二、《算法競賽入門經典》(2)
例子:
1.10082 - WERTYU
知識點:getchar/putchar使用。
技巧:可以使用常量字符串(數組)簡化算法(避免switch等條件選擇語句或複雜轉換)(思想:利用數組下標快速實現轉換:數字->字符)。
(拓展:想到了字符集可移植性(《C陷阱與缺陷》):使用<ctype.h>文件中大小寫轉換和字符類型判定和 char* s = "0123456789" 替代a - '0')
2.272 - TEX Quotes
技巧:純奇偶數判斷可以採用標誌變量1和0做輔助,不斷取反(!),有利於簡化代碼。
多個字符不採用putchar而使用printf(“%s"),有利於簡化代碼。
3.1584 - Circular Sequence
技巧:
gets(line)截止條件時換行符,保留其他空白字符;scanf("%s",line)截止條件是空白字符,忽略開頭非空白字符(空白字符包含空格、tab鍵、回車鍵)。使用時注意上面兩者區別。若一行不包含空白字符,可以用scanf替代gets去讀取一行的數據。
知識點:
最小週期串:方法:枚舉法求最小週期(週期最小爲1,週期最大值爲整串長度。)。速度優化:只考慮能整除整串長度的數做爲週期,可大大減少運算量。
字符串最小表示:
1.暴力求解法,設字符串長度爲n,枚舉n個循環同構字符串,找出最小值。最差時間複雜度O(n^2)。
2.最小表示法:時間複雜度O(n):兩端指針掃描
http://blog.csdn.net/cclsoft/article/details/5467743
http://blog.csdn.net/cclsoft/article/details/5467743
拓展:匹配循環同構字符串:若枚舉匹配需要求模;可以賦值s = s1 + s1,再用s1與s子字符串匹配。
技巧:ACM題不能使用// 註釋,會報錯。使用C:/**/
4.401 - Palindromes
知識點:迴文串和鏡像串。
技巧:儘量使用scanf讀取行,注意輸出要求,像換行有的題要求每段數據結尾,有的題要求兩個數據之間。
拓展:最長迴文串問題。
5.1583 - Digit Generator
知識點:求整數位數及每位的數。關係到每位和時可以通過最大和=位數*9縮小搜索範圍。
其他:第一次提交時錯誤,後面發現對輸入爲個位數的情況,考慮不夠嚴謹,屬於邏輯錯誤。
6.340 - Master-Mind Hints
知識點:建立標記數組緩存各個數狀態。
算法優化:原來算法時間複雜度O(n^2),考慮的數據是1-9,採用位圖數據結構統計並求值,時間複雜度減少到O(n)。