標籤:style blog http color os io ar div 代碼
這個演算法是用來求滿足下列條件的整數x和y:
d = gcd(a,b) = ax+by (d為a,b的最大公約數)
演算法導論上給出的虛擬碼:
EXTENDED_EUCLID(a,b)
1 if b==0
2 return (a,1,0)
3 else (d1,x1,y1) = EXTENDED_EUCLID(b,a mod b)
4 (d,x,y) = (d2,y1,y1-(a/b)*y1)
5 return (d,x,y)
注意第四行是關鍵。
如果看不懂沒關係,下面給出推導過程:
gcd(a,b)==gcd(b,a%b),同時都代入式1,有ax+by==b*x1+(a%b)*y1。
因為 i%j = i-(i/j)*j,所以可以將右邊變形為如下形式
b*x1+(a%b)*y1==b*x1+(a-(a/b)*b)*y1==a*y1+b*(x1-(a/b)*y1),最終得到ax+by==a*y1+b*(x1-(a/b)*y1)
也就是說,上一深度的x等於下一深度的y1,上一深度的y等於下一深度的x1-(a/b)*y1。 需要注意,上面推導時用的除法都是整型除法
例題:
題目連結:http://acm.nyist.net/JudgeOnline/problem.php?pid=775
思路:直接套即可,貼出代碼,方便理解
#include <iostream>#include <cstdio> using namespace std;int x,y,d;//d代表最大公約數void extend_gcd(int a,int b){ int t;//用來記錄當前的x值,因為在計算y的時候會用到 if(b==0) { x = 1; y = 0; d = a; } else { extend_gcd(b,a%b); t = x; x = y; y = t-(a/b)*y; } } int main(){ int a,b; while(scanf("%d %d",&a,&b)!=EOF) { extend_gcd(a,b); printf("%d %d\n",x,y); } return 0;}
參考資料:http://www.cnblogs.com/ka200812/archive/2011/09/02/2164404.html
歐幾裡得演算法的擴充形式