問題引入
給出整數 a , b , n ,問方程 ax + by = n 什麼時候有整數解?如何求出所有的整數解?
有解的充分必要條件是 gcd(a,b) 整除 n
簡單解釋一下,令 a = gcd(a,b) a’ , b = gcd(a,b) b’ ,有 ax + by = gcd(a,b)(a’x+b’y) = n,如果 x , y ,a’ , b’ 都是整數的話,那麼 n 必須是 gcd(a,b) 的倍數纔有解。
例如 4x+6y = 8、2x+3y = 4 有整數解,而 4x+6y = 7沒有整數解。
如果確定有解,一種解題的方法是先找到一個解(x0,y0),那麼通解就爲:
x = x0 + bt , y = y0 - at (t 是任意整數)
利用拓展歐幾里得算法便可以求出特解(x0,y0)
拓展歐幾里得算法
當方程符合ax + by = gcd(a,b)
時,可用拓展歐幾里得算法求出(x0,y0),如下:
void gcdEx(int a,int b,int &x,int &y)
{
if(b == 0){
x=1;
y=0;
return;
}
gcdEx(b,a%b,x,y);
int tmp = x;
x = y;
y = tmp - (a/b)*y;
}
求任意方程 ax + by = n 的一個整數解
用拓展歐幾里得算法得出方程 ax + by = gcd(a,b) 的一個特解後,利用它可以進一步得出任意方程 ax + by = n 的一個解,步驟如下:
- 判斷方程 ax + by = n 是否有整數解,有解的條件是 gcd(a,b) 可以整除 n
- 用拓展歐幾里得算法求 ax + by = gcd(a,b) 的一個解(x0,y0)
- 在 ax0 + by0 = gcd(a,b) 兩邊同時乘以 , 得:
+ = n - 對照 ax + by = n,得到它的一個解(x’0,y’0) 爲:
x’0 = , y’0 =
綜上總的代碼爲:
//拓展歐幾里得算法
void gcdEx(int a,int b,int &x,int &y);//參加上方
int main()
{
int a,b,n,x(0),y(0);
cin>>a>>b>>n;
if(n%__gcd(a,b) == 0){ //第一步判斷方程是否有整數解
gcdEx(a,b,x,y);//第二步求方程 ax+by=gcd(a,b) 的一個特解
x = x*n/__gcd(a,b); //第三步計算 ax+by=n 的解
y = y*n/__gcd(a,b);
cout<<x<<" "<<y<<endl;
}
return 0;
}
應用場合
- 求解不定方程
- 求解模的逆元
- 求解同餘方程