zoukankan      html  css  js  c++  java
  • 扩展欧几里得算法模板

    对于整数a,b,x,y,c

    有a*x+b*y=c,如果c不是a与b的最大公约数的倍数,那么此方程无解

    证明:设gcd(a,b)=d,即最大公约数,那么a*x%d=0,b*y%d=0

    则(a*x+b*y)%d=0,说明c是一个d的倍数,相反的,如果c不是d的倍数,那么次方程无解

    对于欧几里得算法 int extend_eulid(int a,int b,int &x,int &y)

    返回值是a,b的最大公约数,求解的x和y满足a*x+b*y=d的一个解

    那么如何求a*x+b*y=c的解呢?假设x0,y0,是通过欧几里得算出来的一个解,即a*x0+b*y0=d,因为c%d=0

    因此:a*x0*(c/d)+b*y0*(c/d)=d*(c/d)转化为  a*(x0*(c/d))+b*(y0*(c/d))=c

    所以算出a*x+b*y=c的解  x=x0*(c/d), y=y0*(c/d)。

    令r=fabs(b/d);//保证为正数

    minx = (x%r+r)%r为最小非负解(这一点没想明白)

    因为gcd(a,b)=gcd(b,a%b)=d

    a*x+b*y=d,b*x0+(a%b)y0=d

    所以a*x+b*y=b*x0+(a%b)y0

        =b*x0+(a-a/b*b)y0

        =a*y0+b*(x0-a/b*y0)

    因此x=y0, y = x0 – a / b * y0;

    由此可得到递归程序:

     1 #include <iostream>
     2 #include<cstdio>
     3 #include<cstring>
     4 using namespace std;
     5 
     6 int extend_euclid(int a,int b,int &x,int &y)
     7 {
     8     //b等于0时递归结束,得到该步的解,通过该解返回到上一步的出上一步的解
     9     if(b==0)
    10     {
    11         x=1;
    12         y=0;
    13         return a;
    14     }
    15     int d = extend_euclid(b,a%b,x,y);
    16     int t = x;
    17     x=y;
    18     y=t-a/b*y;
    19     return d;//a,b的最大公约数
    20 }
    21 int main()
    22 {
    23     int x,y;
    24     printf("%d
    ",extend_euclid(9,15,x,y));
    25     printf("%d% d
    ",x,y);
    26     return 0;
    27 }
  • 相关阅读:
    剑指 Offer 05. 替换空格
    28. 实现 strStr()
    67. 二进制求和
    排序算法之二快速排序
    排序算法之一冒泡排序
    将本地文件上传到GitHub
    spring data jpa 操作pipelinedb 的continuous view 与stream
    pipelinedb学习笔记
    PostgreSQL 、springboot 、spring data jpa 集成
    pipelineDB学习笔记-2. Stream (流)
  • 原文地址:https://www.cnblogs.com/wt20/p/5754808.html
Copyright © 2011-2022 走看看