码迷,mamicode.com
首页 > 其他好文 > 详细

欧几里得算法的扩展形式

时间:2014-08-24 23:40:53      阅读:339      评论:0      收藏:0      [点我收藏+]

标签:style   blog   http   color   os   io   ar   div   代码   

这个算法是用来求满足下列条件的整数x和y:

                d = gcd(a,b) = ax+by (d为a,b的最大公约数)

 

算法导论上给出的伪代码:

        EXTENDED_EUCLID(a,b)

       1 if b==0

       2   return (a,1,0)

       3 else (d1,x1,y1) = EXTENDED_EUCLID(b,a mod b)

       4   (d,x,y) = (d2,y1,y1-(a/b)*y1)

       5   return (d,x,y)

 

注意第四行是关键。

 

如果看不懂没关系,下面给出推导过程:

  

  gcd(a,b)==gcd(b,a%b),同时都代入式1,有ax+by==b*x1+(a%b)*y1。

  因为 i%j = i-(i/j)*j,所以可以将右边变形为如下形式

    b*x1+(a%b)*y1==b*x1+(a-(a/b)*b)*y1==a*y1+b*(x1-(a/b)*y1),最终得到ax+by==a*y1+b*(x1-(a/b)*y1)

  也就是说,上一深度的x等于下一深度的y1,上一深度的y等于下一深度的x1-(a/b)*y1。    需要注意,上面推导时用的除法都是整型除法

 

例题:

  题目链接:http://acm.nyist.net/JudgeOnline/problem.php?pid=775

思路:直接套即可,贴出代码,方便理解

  

 
#include <iostream>
#include <cstdio> 
using namespace std;
int x,y,d;//d代表最大公约数

void extend_gcd(int a,int b)
{
    int t;//用来记录当前的x值,因为在计算y的时候会用到
    if(b==0)
    {
        x = 1;
        y = 0;
        d = a;
    }
    else
    {
        extend_gcd(b,a%b);
        t = x;
        x = y;
        y = t-(a/b)*y;
    } 
} 

int main()
{
    int a,b;
    while(scanf("%d %d",&a,&b)!=EOF)
    {
            extend_gcd(a,b);
        printf("%d %d\n",x,y);
    } 
    
    return 0;
}

        

 

参考资料:http://www.cnblogs.com/ka200812/archive/2011/09/02/2164404.html

 

欧几里得算法的扩展形式

标签:style   blog   http   color   os   io   ar   div   代码   

原文地址:http://www.cnblogs.com/ltwy/p/3933704.html

(0)
(0)
   
举报
评论 一句话评论(0
登录后才能评论!
© 2014 mamicode.com 版权所有  联系我们:gaon5@hotmail.com
迷上了代码!