poj1061-exgcd

网上找答案 发现这道题需要用到exgcd的知识 先把百度的gcd exgcd贴上来:

gcd函数就是用来求(a,b)的最大公约数的。gcd函数的基本性质:gcd(a,b)=gcd(b,a)=gcd(-a,b)=gcd(|a|,|b|)

一个有用的公式:

gcd(a,b)=gcd(b,a mod b)
C++语言实现
1
2
3
int  gcd( int  a, int  b){
     return  b?gcd(b,a%b):a;
}

exgcd

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

扩展欧几里德算法是用来在已知a, b求解一组x,y使得ax+by = Gcd(a, b) =d

c++语言实现

1
2
3
4
5
6
7
8
9
10
11
int  exGcd( int  a, int  b, int  &x, int  &y)
{
     if (b==0)
     {
         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;
}

所以这道题其实就是求ax+by=c中的x
其中,a=m-n b=L c=y-x 
所以最后的程序:

#include<cstdio>

#include<iostream>

#include<cstring>

#include<algorithm>

using namespace std;

long long int LL;


long long int exgcd(long long int a,long long int b,long long int &x,long long int &y)

{

    if(b==0)

    {

        x=1; y=0;

        return a;

    }

    long long int t=exgcd(b,a%b,x,y);

    long long int tmp=x;

    x=y;

    y=tmp-a/b*y;

    

    return t;

}


int main()

{

    long long int x,y,m,n,mod;

    while(~scanf("%lld%lld%lld%lld%lld",&x,&y,&m,&n,&mod))

    {

        if(m==n) puts("Impossible");

        else

        {

            if(m<n) swap(m,n),swap(x,y);

            long long int a,k;

            long long int c=y-x;

            long long int d=exgcd(m-n,mod,a,k);

            

            if(c%d) {

              printf("Impossible\n");

            }

            else printf("%lld\n",((a*c/d)%(mod/d)+(mod/d))%(mod/d));

        }

    }

    return 0;

}



猜你喜欢

转载自blog.csdn.net/Jazzmine/article/details/78080323