zoukankan      html  css  js  c++  java
  • 扩展欧几里得算法(含严谨证明)

    要整扩展欧几里得,我们肯定要学会欧几里得算法,如果你没有学过gcd(a,b)=gcd(b,a%b),那么打开这个链接:欧几里得算法

    好了,如果你已经学完了欧几里得,那么就能默认你知道gcd(a,b)=gcd(b,a%b),那么什么是扩展欧几里得,就是对于ax+by=gcd(a,b),一定有一组整数解x,y(注意!不要用24和36这个例子卡我,x,y是整数,可以为负的!)

    在证明之前,我们需要明确一种术学上的证明工具,数学归纳法:

        最简单和常见的数学归纳法是证明当n等于任意一个自然数时某命题成立。证明分下面两步:

        证明当n= 1时命题成立。

        假设n=m时命题成立,那么可以推导出在n=m+1时命题也成立。(m代表任意自然数)

        然后命题得证。

        而在递归式中也是如此。但是会有所不同

    当b=0时,很明显,这个定理时成立的,y取0,x取1,那么等式成立

    现在只需要证,假设定理gcd(b,a%b)成立,那么定理在gcd(a,b)中也成立就行。

    假设,b*x2+a%b*y2=gcd(b,a%b)时存在解x2,y2

    那么,需要证明,a*x1+b*y1=gcd(a,b)存在解x1,y1,

    我们令a=k*b+c,也就是c是a%b.

    移项得:c=a-k*b.将这个式子代入到需要证明的式子:b*x2+(a-k*b)*y2=gcd(b,a%b),再将其运用乘法分配律:b*x2+a*y2-k*b*y2=gcd(b,a%b)

    再合并同类项:a*y2+b*(x2-k*y2)=gcd(b,a%b)=gcd(a,b)

    我们只需要让x=y2,y=(x2-k*y2)不就行了?

    得证,然后代码实现过程也是怎么写的。

    (已知a、b,求一组解x、y使ax+by=gcd(a,b))

    #include <iostream>
    #include <cstdlib>
    #include <cstring>
    #include <algorithm>
    #define REP(i,k,n)  for(int i=k;i<=n;i++)
    #define in(a) a=read()
    using namespace std;
    inline int read(){
        int x=0,f=1;
        char ch=getchar();
        for(;!isdigit(ch);ch=getchar())
            if(ch=='-')
                f=-1;
        for(;isdigit(ch);ch=getchar())
            x=x*10+ch-'0';
        return x*f;
    }
    int x,y,t,A,B,d;
    inline void exgcd(int a,int b,int &x,int &y,int &d){
        if(!b)  d=a,x=1,y=0;
        else  exgcd(b,a%b,x,y,d),t=x,x=y,y=t-a/b*y;
    }
    int main(){
        in(A),in(B);
        exgcd(A,B,x,y,d);
        cout<<d<<" "<<x<<" "<<y;
    }
        

     最后,再说一下怎么通过扩展欧几里得解不定方程ax+by=c.(x、y为整数)

    首先,我们必须保证,c能整除gcd(a,b)要不然就无解

    然后我们找特解:讲a,b除以gcd(a,b),得到a0,b0使他们互质,再用扩展欧几里得求a0*x+b0*y=1的解x0,y0(这组解是特解)

    然后通解就是x=x0+b0*t,y=y0+a0*t。

  • 相关阅读:
    Java集合框架--List 遍历
    Java集合框架--List 类
    Leetcode 239 Sliding Window Maximum (指定滑动窗最大值) (滑动窗口)
    Vim配置
    子字符串模板 (双指针, 滑动窗口)
    Leetcode 76 Minimum Window Substring. (最小窗口子字符串) (滑动窗口, 双指针)
    Leetcode 3 Longest Substring Without Repeating Characters. (最长无重复字符子串) (滑动窗口, 双指针)
    一切从赞美开始
    Leetcode 10 regular expression matching (正则表达式匹配) (动态规划)
    Leetcode 5 Longest Palindromic Substring (最长回文子字符串)(动态规划)
  • 原文地址:https://www.cnblogs.com/jason2003/p/9799927.html
Copyright © 2011-2022 走看看