扩展欧几里得算法与二元一次方程的整数解

问题引入

给出整数 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 的一个解,步骤如下:

  1. 判断方程 ax + by = n 是否有整数解,有解的条件是 gcd(a,b) 可以整除 n
  2. 用拓展欧几里得算法求 ax + by = gcd(a,b) 的一个解(x0,y0)
  3. 在 ax0 + by0 = gcd(a,b) 两边同时乘以 n g c d ( a , b ) {n \above{0.5pt} gcd(a,b)} , 得:
    a x 0 n g c d ( a , b ) {ax_0n \above{0.5pt} gcd(a,b)} + b y 0 n g c d ( a , b ) {by_0n \above{0.5pt} gcd(a,b)} = n
  4. 对照 ax + by = n,得到它的一个解(x0,y0) 为:
    x0 = x 0 n g c d ( a , b ) {x_0n \above{0.5pt} gcd(a,b)} , y0 = y 0 n g c d ( a , b ) {y_0n \above{0.5pt} gcd(a,b)}

综上总的代码为:

//拓展欧几里得算法
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;
}

应用场合

  1. 求解不定方程
  2. 求解模的逆元
  3. 求解同余方程

猜你喜欢

转载自blog.csdn.net/weixin_45826022/article/details/106190901