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

好吧,過年在家還是看了點點書,還自己給自己出了兩道坑爹題。

這道題目一開始想了半天敲出來了,但是隻對一組數據得出的答案是對的。。。。後來又寫了一遍就對了。。。。

描述:

  求出方程: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;
}


發表評論
所有評論
還沒有人評論,想成為第一個評論的人麼? 請在上方評論欄輸入並且點擊發布.
相關文章