• (转)拓展欧几里得算法


    描述:对于不完全为 0 的非负整数 a,b,gcd(a,b)表示 a,b 的最大公约数,必然存在整数对 x,y ,使得 gcd(a,b)=ax+by。

    解法描述:设 a>b, 当 b=0,gcd(a,b)=a,此时 x=1,y=0; ab<>0 时,
      设 ax1+by1=gcd(a,b);
       bx2+(a mod b)y2=gcd(b,a mod b);
      因为gcd(a,b)=gcd(b,a mod b);
      则:ax1+by1=bx2+(a mod b)y2;
      即:ax1+by1=bx2+(a-(a/b)*b)y2=ay2+bx2-(a/b)*by2;
      根据恒等定理得:x1=y2; y1=x2-(a/b)*y2;
      这样我们就得到了求解 x1,y1 的方法:x1,y1 的值基于 x2,y2.
      上面的思想是以递归定义的,因为 gcd 不断的递归求解一定会有个时候 b=0,所以递归可以结束。

    代码:

    #include <stdio.h>
    #include <stdlib.h>
    
    //全局变量
    int x,y;//希望求出的系数: x*a + y*b= c
    int tmpx,tmpy;
    
    //求最大公约数
    int gcd(int num1, int num2)
    {
        if(0==num2)
        {
            return num1;
        }
        else
        {
            return gcd(num2, num1%num2);
        }
    
    }
    
    void extend_euclid(int a,int b,int c)
    {
        if(0==a)
        {
           x=0;y=1;
           return;
        }
        else if(0==b)
        {
            x=1;y=0;
            return;
        }
        else
        {
            extend_euclid(b,a%b,c);
            tmpx=x;
            tmpy=y;
            x=tmpy;
            y=tmpx-(a/b)*tmpy;
            return;
        }
    }
    
    int main()
    {
        int a,b;//用户输入
        int c;//最大公约数
    
        while(2==scanf("%d %d",&a,&b))
        {
            if(0==a && 0==b)//a,b为不全为0的整数
                return -1;
    
            c=gcd(a,b);
            extend_euclid(a,b,c);
            printf("最大公约数是%d\n",c);
            printf("x=%d, y=%d\n",x,y);
        }
        return 0;
    }
  • 相关阅读:
    如何使用和关闭onbeforeunload 默认的浏览器弹窗事件
    用js怎么来判断我已点击了窗体中“关闭”按钮?
    js实现时分秒毫秒计时器
    史上最详细的JavaScript事件使用指南
    【JavaScript】图片加载由模糊变清晰 —— 图片优化
    熟悉 hybrid
    深入理解事件委托
    架构师 资料
    常用工具网站集合
    前端路由实现.
  • 原文地址:https://www.cnblogs.com/Antech/p/2812516.html
Copyright © 2020-2023  润新知