這幾天雜七雜八的事情太多,再加上進入了考試周,所以很難有時間安安靜靜的敲敲**,看看書,寫寫部落格了。最近寫了一些oj的題目,但是寫到這個份上,發現有些做不動了。因為自己沒有很系統的看過一些演算法競賽書,所以很多時候時間複雜度和空間複雜度都控制不好,所以就想寫一寫前段時間買的劉汝佳的紫書,也就是《演算法競賽入門經典》的學習筆記。目前只把前兩章看完了。
其實前兩章的內容比較淺,還大部分都是基礎的知識。但是也體現了演算法競賽和平常打**的不同。在演算法競賽中我們不要列印一些無關的資訊,我們平時這樣做可能是為了介面的友好等等。但是競賽對於輸出和輸入的格式很嚴格,那樣做無疑是自取煩惱。
我們來乙個很簡單的例子,就是兩個變數a和b相互交換。我們首先想到的應該就是三變數交換的方法,但是書上還寫出了另外三種答案:
第一種:
inta,b;
scanf(
"%d %d
",&a,&b);
a=a+b;
b=a-b;
a=a-b;
第二種:
inta,b;
scanf(
"%d %d
",&a,&b);
a^=b;
b^=a;
a^=b;
如果說第一種還比較好理解的話,那麼第二種是用異或運算子是什麼意思呢?記得在之前的一篇blog:我寫過所有數值在計算機都是用二進位制儲存的,所以^可以看成兩個數相加。那麼b^=a;則是把a中與b相同的位全部變為0(a此時為a+b),從而獲得了a原來的值。同理a可以獲得b原來的值。這兩種方法當時讓我看到的時候覺得很是巧妙,因為省略了乙個變數。但當我繼續往下讀的時候,lrj認為這些方法都不好,因為演算法競賽大都使用的是黑盒測試,所以並不關心使用了什麼方法。那麼解決這個問題的最好方法無疑是這樣:
inta,b;
scanf(
"%d %d
",&a,&b);
printf(
"%d %d
",b,a);
的確是讓人很無語,不過這也貌似告訴我們如果走投無路的時候打表貌似是一種很好的方法qaq。。。
同時我們在知道一些數學公式的時候,比如說等差求和等,我們最好採用公式的方法,而不是迴圈來減少程式的執行時間。
而第二章,則主要講的是迴圈結構。然後重點介紹了迴圈的代價,很浪費時間容易導致執行超時。還會出現資料溢位,這在競賽中無疑是萬分致命的。有幾道題目還是很有意思的:
1.分數化小數
輸入正整數a,b,c,輸出a/b的小數形式,精確到小數點後c位。a,b<=10^6,c<=100.輸入包含多組資料,結束標記為a=b=c=0。
樣例輸入:
1 6 4
0 0 0
樣例輸出:
case 1: 0.1667
**:
#include intmain()
/*進行第c位的判斷來確定四捨五入
*/mod*=10
; c1=mod/b;
mod%=b;
if((mod*10/b)>=5
) c1++;
printf("%d
",c1);
printf("\n
");}
return0;
}
2.排列
用1~9組成三個三位數abc,def,ghi,每個數字恰好使用一次,要求abc:def:ghi=1:2:3.按照」abc def ghi」的格式輸出所有解每行乙個解。
**:
#include intmain()
//完成三個數的各位的儲存
for(k=1;k<=9;k++)
}if(!flag)
continue
;
else
printf(
"%d %d %d\n
",i,i*2,i*3
); }
}
當然這道題暴力當然也可以,寫一堆判定條件就好了,但是運用陣列自認為是很簡潔的一種方法。
前兩章感覺還沒有完全進入競賽的階段,繼續往下估計收穫會更大。
西瓜書 學習筆記 (1)緒論
個人自學筆記,內容摘自原書 個人理解,不一定正確,若有誤,歡迎指出。機器學習的定義 假設用p來評估電腦程式在某任務類t上的效能,若乙個程式通過利用經驗e在任務t中獲得了效能改善,則我們就說關於t和p,該程式對e進行了學習。mitchell,1997 通俗地說,機器學習即是通過學習演算法,從經驗 資料...
花書學習筆記 雜記
關於貝葉斯學派和頻率學派的問題 每次提到貝葉斯學派和頻率學派的不同之處時,人們都會使用這個例子 給定資料集xda ta x xd ata 如果我們想要確定某乙個引數 theta 頻率學派的做法是arg max mathop limits theta argmax 也就是說 認為 theta 是乙個確...
編譯原理(龍書)學習之路(1)
在第三章末尾,有一節介紹了由正規表示式直接生成dfa的方法。需要三個輔助函式nullable,firstpos,lastpos和followpos。其中前三個都很好計算也很好理解,而followpos雖然通過例子知道了如何計算,但演算法中對它的原理介紹卻十分含糊。書上是這麼說的 如果n是乙個cat結...