POJ1061 青蛙的约会(拓展欧几里德)
题意:
中文题不解释
要点:
拓展欧几里德求最小整数解问题,一开始在怎么取最小整数解的问题上卡了,同余这块也得学了。
参考博客:点击打开链接
15408079 | Seasonal | 1061 | Accepted | 164K | 0MS | C++ | 588B | 2016-04-18 21:50:45 |
#include<stdio.h>
#include<string.h>
#include<stdlib.h>
__int64 e_gcd(__int64 a, __int64 b, __int64 &x, __int64 &y)//一开始用long long出错,不知道为什么
{
__int64 ans, temp;
if (b == 0) //如果b为0,说明为边界条件
{
x = 1; y = 0;
return a;
}
ans = e_gcd(b, a%b, x, y);
temp = x;
x = y;
y = temp - a / b*y; //这里都是数学证明,可以参考博客
return ans;
}
int main()
{
__int64 x, y, m, n, l,xx,yy,r,d;
while (scanf("%I64d%I64d%I64d%I64d%I64d", &x, &y, &m, &n, &l) != EOF)
{
d = e_gcd(n - m, l, xx, yy);
if ((x - y) % d != 0)
printf("Impossible\n"); //性质:如果c无法整除gcd(a,b)那肯定无解
else
{
xx *=(x - y) / d; //将x*(c/gcd(a,b))来求ax+by=c的解
r = l / d; //性质:通解为x0+k*b/gcd(a,b),k为任意值
xx = (xx%r + r) % r; //这里因为xx可能为负数,所以先整除r得到最接近0的解,再加r并%r确保是正数
printf("%I64d\n", xx);
}
}
return 0;
}