zoukankan      html  css  js  c++  java
  • 扩展欧几里得算法求二元一次方程

    二元一次方程的定义:

        含有两个未知数,并且含有未知数的项的次数都是1的整式方程做二元一次方程。所有二元一次方程都可化为ax+by+c=0(a、b≠0)的一般式与ax+by=c(a、b≠0)的标准式,否则不为二元一次方程。

    求最大公约数

    int  gcd(int a,int b)//a,b为两个数。
    {
        if(b==0)
            return a;
        else
            return gcd(b,a%b);
    }

    拓展欧几里得算法

    int exgcd(int a,int b,int &x,int &y)
    {
        if(b==0){
            x=1;
            y=0;
            return a;
        }
        else{
            int r=exgcd(b,a%b,y,x);
            y-=(a/b)*x;
            return r;
        }
    }

    求一组特解代码:

     if(n%__gcd(a,b) == 0){ //第一步判断方程是否有整数解
          exgcd(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;
    }

    求通解

    现在我们来考虑构造通解( 特解是X、Y ):

    由于已经满足 aX+bY=c , 两个未知数的关系类似于加权和固定,若一个增大,则另一个一定按比例减小,显然满足关系:

    a(X+nb)+b(Y-na)=c

    X 每变化 b 的整数倍,Y 就反向变化 a 的同等倍数。似乎构造出了通解表达式 X+nb 、Y-na 。

    但是我们会发现一个问题,就是 a 、b 不一定是最小的步长,可能会 “跳过” 许多解。

    为了求得最小步长,我们应该对 a 、b 同时除以某个整数,使得商也是整数,就求出了每次最小的变化量。很明显,应除以

    gcd(a, b)

    所以,通解应该是

     X+n*b/gcd(a,b)\, \, ,\, \, Y-n*a/gcd(a,b)

    举例:(待修改)

        for(int i=0;i<=1000;i++){
            int newx = x+i*b/__gcd(a,b);
            int newy = y-i*a/__gcd(a,b);
            if(newx>=0&&newy>=0){
                cout<<"newx= "<<newx<<"     newy="<<newy<<endl;
            }
        }

     参考:

    https://blog.csdn.net/weixin_43810158/article/details/87973511

    https://blog.csdn.net/Originum/article/details/81437027

     

    因上求缘,果上努力~~~~ 作者:每天卷学习,转载请注明原文链接:https://www.cnblogs.com/BlairGrowing/p/13885812.html

  • 相关阅读:
    浏览器拦截跨域请求处理方法
    如何保护java程序不被反编译
    python面对对象面试题
    面向对象之继承
    面向对象之多态
    面向对象之组合
    面向对象初始
    python之匿名函数
    python之内置函数
    azure连接redis
  • 原文地址:https://www.cnblogs.com/BlairGrowing/p/13885812.html
Copyright © 2011-2022 走看看