啊。。我是一条咸鱼鱼
扩展欧几里德算法
基本算法:对于不完全为 0 的非负整数 a,b,gcd(a,b)表示 a,b 的最大公约数,必然存在整数对 x,y ,使得 gcd(a,b)=ax+by。
证明:设 a>b。
1,显然当 b=0,gcd(a,b)=a。此时 x=1,y=0;
2,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,所以递归可以结束。
long long exgcd(long long a,long long b,long long& x,long long& y)
{
if(!b)
{
x=1;
y=0;
return a;
}
long long r=exgcd(b,a%b,y,x);
y-=a/b*x;
return r;
}//r=gcd(a,b)
青蛙的约会
1 2 3 4 5Sample Output
4
#include
#include
#include
#include
#include
#include
using namespace std;
long long exgcd(long long a,long long b,long long &x,long long &y){
if(b==0){
x=1;
y=0;
return a;
}
long long ans=exgcd(b,a%b,y,x);
y-=a/b*x;
return ans;
}
long long x,y,m,n,l,t,temp,gcd,p;
int main(){
while(scanf("%lld%lld%lld%lld%lld",&x,&y,&m,&n,&l)!=EOF){
gcd=exgcd(n-m,l,t,p);
if((x-y)%gcd){
printf("Impossible\n");
}
else{
t=(x-y)*t/gcd;
temp=l/gcd;
t=(t%temp+temp)%temp; //寻找最小正整数 不太懂
printf("%lld\n",t);
}
}
return 0;
}