/*
Name:青蛙约会 (扩展欧几里德)
Actor:HT
Time:2015年7月31日
Error Reporte:
}
*/
#include "stdio.h"
#include "string.h"
#include "iostream"
using namespace std;
int x,y;
//ax+by=gcd(a,b)
int gcd(int a,int b)
{
if (b==0)
{
x = 1;
y = 0;
return a; //b==0时,gcd(a,0)==a,因此x=1,y=0
}
int d = gcd(b,a%b);
//ax + by =gcd(a,b) = gcd(b,a%b) = b*x0 + a%b*y0 = b*x0 + (a-a/b*b)*y0 = a*y0 + b*(x0-a/b*y0)
//因此 本层的x 等于上一层的y,本层的y 等于上一层的(x-a/b*y)
int temp = x;
x = y;
y = temp - a/b*y;
//debug:printf("%d %d\n",x,y);
return d;
} //此时的x y是ax+by=gcd(a,b)的一组特殊解
//扩展欧几里德
//ax + by = gcd(a,b) ---> (ax + by) * (c/gcd(a,b)) == gcd(a,b) * (c / gcd(a,b))
// ---> 新x = x * (c/gcd(a,b)) 新y = y * (c/gcd(a,b)) 这是ax+by=c的一组特解
//通解: X = x + (b/gcd) * T
// Y = y - (a/gcd) * T
int main()
{
//青蛙约会 x/y m/n L
int pa,pb,m,n,l;
int a,b,c,ans;
while(scanf("%d %d %d %d %d",&pa,&pb,&m,&n,&l)!=EOF)
{
//( pa + T*m ) - ( pb + T*n ) == l * K
//(n-m)*T + l*K == pa-pb 注意正负号
a=n-m;
b=l;
c=pa-pb;
int g = gcd(a,b); //此时求得一组特解,但未必最小
if(c%g!=0) //题意可知,X作为次数T,一定是整数,X=x*(c/g),若c/g非整,X非整,则无解
{
printf("Impossible\n");
continue;
}
x=x*(c/g);
y=y*(c/g);
//当X最小时,由X=x + (b/gcd)*T 当T是使X大于零且最小的值即可
//那么 令X=0,x = (b/gcd)*T -----> T=x*gcd/b
//※※ps:整型除法--得到的将会是使b/gcd最接近x的T,可能大于可能小于 ,如果大于了,就减去一个b/gcd就好
int t = x*g/b;
ans = x - t*b/g;
if(ans<0) ans+= b/g;
printf("%d\n",ans);
}
}
[数论]青蛙约会 (扩展欧几里德)
最新推荐文章于 2018-09-16 20:13:02 发布