您的位置:首页 > 其它

拓展欧几里得解方程ax+by=gcd(a,b)

2015-02-26 15:24 323 查看
好吧,过年在家还是看了点点书,还自己给自己出了两道坑爹题。

这道题目一开始想了半天敲出来了,但是只对一组数据得出的答案是对的。。。。后来又写了一遍就对了。。。。

描述:

求出方程:ax+by=gcd(a,b)的初始解,输入a,b(int),输出x,y(空格隔开);

输入:

60 22

22 60

12453 2467

输出:

-4 11

11 -4

304 -1613

代码:

#include<stdio.h>
void swap(__int64 &a,__int64 &b)
{
     a^=b;
     b^=a;
     a^=b;
}
__int64 gcd(__int64 a,__int64 b)
{
     return b?gcd(b,a%b):a;
}
void func(__int64 a,__int64 b)
{
     int f;
     f=0;
     if(a<b)
    {
        swap(a,b);
        f=1;
     }
     __int64 x1=1,x2,x,y1=1,y2,y,p,q,r1,r2,r;
     r1=a%b;r2=b%r1;
    q=a/b;p=b/r1;r=r1%r2;
     x1=1;y1=-q;
     x2=-p;y2=1+p*q;
 //    printf("1\n x1:%d y1:%d\n x2:%d y2:%d\nq:%d\n",x1,y1,x2,y2,q);
     while(r!=0)
    {
        q=r1/r2;
        r1=r2;r2=r;
        r=r1%r2;
        x=x1-q*x2;
        y=y1-q*y2;
        x1=x2;x2=x;
        y1=y2;y2=y;

//      printf("\n2\n x1:%d y1:%d\n x2:%d y2:%d\n x:%d y:%d\nq:%d\n",x1,y1,x2,y2,x,y,q);
    }
//    printf("a=%I64d b=%I64d\n",a,b);
    if(f==0)
        printf("x=%I64d y=%I64d\n",x2,y2);
    else
        printf("x=%I64d y=%I64d\n",y2,x2);
//    if(x*a+y*b==gcd(a,b))   //这一段是写的时候验算用的。。
//        printf("Yes\n");
//    else
//        printf("No!\n");
}
int main()
{
    __int64 a,b;
    //freopen("Data.txt","r",stdin);
    //freopen("Out.txt","w",stdout);
    while(scanf("%I64d%I64d",&a,&b)!=EOF)
        func(a,b);
    return 0;
}
主要思路是求出第一二个系数,然后用前两个可以推出后一个。就是这样。

Ps:2015.3.27补充:

后来我在别人博客看到了一个更厉害的写法,就摘下来了,然后加上了手脚。。。简直对于我这样的渣来说简直屌炸了!
#define LOCAL
#include<stdio.h>
int exgcd(int a, int b, int &x, int &y) {
if (!b) {
x = 1;
y = 0;
return a;
}
int r = exgcd(b, a % b, x, y);
int t = x;
x = y;
y = t - a / b * y;
return r;
}
int main() {
int a, b, x, y;
#ifdef LOCAL
freopen("Data.txt", "r", stdin);
freopen("Out.txt", "w", stdout);
#endif
while (scanf("%d%d", &a, &b) != EOF) {
exgcd(a, b, x, y);
printf("x=%d\ty=%d\n", x, y);
}
return 0;
}
内容来自用户分享和网络整理,不保证内容的准确性,如有侵权内容,可联系管理员处理 点击这里给我发消息
标签: