zoukankan      html  css  js  c++  java
  • 扩展欧几里德算法~简单

    之前一直知道扩展欧几里德算法的实现代码,但是原理一直还是模模糊糊,看了很多终于明白了,于是决定写一篇来记录下自己的思路。

    下面实现的其他定理就不再多解释了,主要讲扩展欧几里德算法。

    扩展欧几里德算法就是用来求 Ax+By=K 的一组解,  A,B,K 都是已知常量,求解 x, y.

    首先,根据“贝祖等式“可知,

            Ax1+By1=gcd(A,B).

    所以我们可以接着推出

           C =A%B.

           Bx2 + Cy2 = gcd(B,C)

            =  Bx2 + (A%B)y2 = gcd( B, A%B ).

    然后我们再接着推个用到的

          A%B=[A-(A/B)*B]. //这一步要注意下,这里的  ‘A/B’是计算机中的A/B,不保留小数的 

    最后,我们可以来总推了

          Ax1 + By1 = gcd( A, B ) .

          C=A%B.

          Bx2 + Cy2 = gcd( B, C ).

          gcd( A, B ) = gcd( B, C ).//划重点

       所以

          Ax1 + By1 = Bx2 + Cy2

          Ax1 + By1 = Bx2 + ( A%B )y2

          Ax1 + By1 = Bx2 + [ A - (A/B) * B ]y2

          Ax1 + By1 = Bx2 + Ay2 - [ (A/B) *B]y2

       根据恒等定理得

          Ax1 = Ay2

          By1 = Bx2 -  B*[ (A/B) *y2 ] = B * [ x2 - (A/B)*y2 ]

       所以

          x1 = y2

          y1 = x2 - (A/B)*y2

      

       仔细观察下这其实就是个递推的过程

          因为 x1要从 y2得来 ,   y1要从  x2 - (A/B)*y2得来

              而 x2 要从 y3 得来 , y2要从  x3 - (A/B)*y3得来

           .........................................................................

             最终Xn-1 要从 Yn得来,Yn-1 要从 Xn - (A/B)*Yn

           //注意,这里的A和B的值, 每次都不一样, A 和 B 不断的替换为 A=B , B=A%B,其实就是gcd的参数变换

       那么这个递推的边界在哪里呢?

          假设 A>0  B=0

          则  gcd( A, B )=A.

          则  Ax + By =gcd ( A,B )

          可以推出  x=1, y=0.

          那么边界就是当 B=0的时候,  赋值 x=1,y=0 然后返回

    ————————————————————————————————————————分割线————————————————————————————————————————

    下面给出两个实现代码,一个是简单流程实现版,一个是代码简化版,建议看懂第一个 然后 用 第二个 

    //简化版
    int
    gcd_pro(int A, int B, int &x, int &y) { if (B == 0) { x = 1; y = 0; return A; } else { int ans; int x_temp, y_temp; x_temp = x; y_temp = y; ans=gcd_pro(B, A%B, x_temp, y_temp); x = y_temp; y = x_temp - (A / B)*y_temp; return ans; } }
    //白书版
    int
    gcd_pro(int A, int B, int &x, int &y) { if (B == 0) { x = 1; y = 0; return A; } else { int ans; ans = gcd_pro(B, A%B, y, x); y -= (A / B)*x; return ans; } }

    不过,我们经常性是要解决  Ax + By=C 这样的方程,知道了 Ax + By = gcd(A,B)的解又有什么用呢?

    我们只要把  Ax + By = gcd(A,B) 得出的 x 和 y,

    乘等于 C / gcd(A,B) 就得到 Ax + By = C 的解

    下面给出例子

    #include<iostream>
    #include<algorithm>
    #include<string>
    #include<vector>
    #include<queue>
    using namespace std;
    
    int gcd_pro(int A, int B, int &x, int &y)
    {
        if (B == 0)
        {
            x = 1;
            y = 0;
            return A;
        }
        else
        {
            int ans;
            ans = gcd_pro(B, A%B, y, x);
            y -= (A / B)*x;
            return ans;
        }
    }
    
    int main() 
    {
        int ans;
        int x_ans, y_ans;
        int A_ans, B_ans, C_ans;
    
        x_ans = y_ans = 0;
        cin >> A_ans >> B_ans >> C_ans;
    
        ans=gcd_pro(A_ans, B_ans, x_ans, y_ans);

        x_ans *= C_ans/ans;
        y_ans *= C_ans/ans;

    
    
        cout << ans << endl << x_ans << ' ' << y_ans << endl;
    
        return 0;
    }
  • 相关阅读:
    K8s学习笔记
    NETCore在Centos下的内存泄漏排查
    搭建Linux下GO的开发环境
    Docker 运行mysql8.0挂载数据卷
    一张图解释Docker
    NetCore基于Consul+Ocelot+Docker+Jenkin搭建微服务架构
    Jenkins+Docker+Git实现自动化部署
    使用阿里云容器镜像服务示例
    Go重新学习记录
    软谋在线教育诚招php,java,.net,设计师讲师(可兼职)
  • 原文地址:https://www.cnblogs.com/caibingxu/p/10587680.html
Copyright © 2011-2022 走看看