趕快加入我們來參與討論吧!
您需要 登錄 才可以下載或查看,沒有帳號?加入我們
x
本帖最後由 jd3 於 2014-9-23 00:19 編輯
讀完題目應該能發現其實只是求最大公因數(GCD)
標準作法:輾轉相除
作弊作法:__gcd() ---> 請不要使用這個不營養的東西,參考函式內容就好
Q:為什麼不使用__gcd()
A:不一定到哪都能用,有的比賽也不給你CE訊息會悲劇
只要看到底線就要知道這是一堆工程師避免衝突的共同壞習慣所產生的,一個底線用完不夠就再加一個,前面太多了就加後面......
自己實作也比較容易懂,如果你要打比賽以後也會用到輾轉相除法的延伸
輾轉相除法:
遞迴式:
(a>b) gcd(a,b) = gcd(b, a%b)
證明:
我用個我認為比較好說明的方法
a%b 必定是 a 減去 整數*b
所以只要能證明 gcd(a,b) = gcd(a, a-b) 就就好了
令 gcd(A,B) = x , gcd(B, A-B) = y
讓我們把已知條件列出來(管他有沒有用到)
首先可知:
A%x = 0
B%x = 0
B%y = 0
(A-B)%y = 0
由於A,B 都是 x 的整數倍:
(A-B)%x = 0
由於(A-B), B 都是 y 的整數倍:
A%y = 0
綜合以上,稍微找一下就能證明:
x 是 gcd(A,B) 且 y是A,B的公因數
所以y<=x
y 是 gcd(B, A-B) 且 x是B,(A-B)的公因數
所以x<=y
這樣就知道 x=y
得證: gcd(a,b) = gcd(a, a-b) 成立
實作:
以下附上簡短的實作方法
速度算快的
首先是__gcd()裡的方法
[C++] 純文本查看 復制代碼 inline void GCD(int a, int b)
{
while (b != 0)
{
int c = a % b;
a = b;
b = c;
}
return a;
}
再來是最簡短的方法
雖然用到比較多次MOD
但是少了交換,速度不會差多少
[C++] 純文本查看 復制代碼 inline void GCD(int a, int b)
{
while((a%=b) && (b%=a));
return a+b;
}
|