题目链接:点击打开链接
这道题看了很多个题解(刚接触数论方面的题目)...然后自己总结了一个更容易看懂的一篇题解。
参考链接:
http://blog.sina.com.cn/s/blog_59825cee0100la9u.html
http://blog.youkuaiyun.com/loi_dqs/article/details/49488851
1.
由题目中给出的数据,可以看出两只青蛙在碰面了过后的位置相当于(x+tm)%L,(y+tm)%L (k是设的青蛙跳了多少步后碰面)
相当于解方程
x+tm≡y+tn (mod L)
尝试化简,
(x+tm)+p*L=y+tn(p为任意整数)
拆括号,则变成了
(m-n)*t+L*p=y-x
终于变成了我们所熟悉的ax+by=c的形式
令m-n=a,L=b,y-x=c;
那就是解
a*t+b*p=c
中t的最小值
但是,问题来了,我们不能保证a*t+b*p=c是有解的
如果方程无解
那么c一定不整除gcd(a,b),因为方程左边肯定可以整除gcd(a,b)
那如果有解呢...
(敲黑板!重点来了)
(以下摘自大佬2的证明过程 然后修改了一点)
设要解的方程(求x)是:
而我们已经解得
此时将第二个方程左右同时乘c/d,则可得:
所以:
这样并没有完,因为这只是一组解,我们要求最小正整数解。
我们知道:若一组 < x,y > 是ax+by=c的一组解,那么
(把这两个带进原方程,你会发现抵消了一些项,可以证明)
也是原方程的一组解。
这样我们只需要让解得的x不断减b/d
,直到再减就为负数时,所得的x就是我们要的解。
其实这个过程就是模运算,所以最小正整数解就是:
附上代码
#include<iostream>
#include<algorithm>
using namespace std;
typedef long long LL;
LL x,y,m,n,L;
LL x1,y1;
LL d;
void exgcd(LL a,LL b)
{
if(b==0)
{
x1=1;
y1=0;
d=a;
}
else
{
exgcd(b,a%b);
LL temp=x1;
x1=y1;
y1=temp-(a/b)*y1;
}
}
int main()
{
while(cin>>x>>y>>m>>n>>L)
{
if(m==n)
{
cout<<"Impossible"<<endl;
continue;
}
LL a=m-n;
LL b=L;
LL c=y-x;
if(a<0)
{
a=-a;
c=-c;
}
exgcd(a,b);
if(c%d)
{
cout<<"Impossible"<<endl;
}
else
{
x1=x1*c/d;
b=b/d;
if(x1>=0)
x1=x1%b;
else
x1=x1%b+b;
if(x1==0)
x1=b;
cout<<x1<<endl;
}
}
return 0;
}