为什么先出例题呢,因为对其中一些理论还没有搞清楚
扩展欧几里得算法模板:
long long exgcd(long long a,long long b,long long &x,long long &y)///得到ax+by=gcd(a,b)的一组解
{ ///同时返回gcd(a,b)
if(b==0)
{
x=1;
y=0;
return a;
}
long long ans=exgcd(b,a%b,x,y);
long long temp=x;
x=y;
y=temp-a/b*y;
return ans;
}
例题一:青蛙约会问题(pku 1061)
分析:两个目标都在动,最终到达同一点的问题
#include<cstdio>
#include<iostream>
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,x,y);
long long temp=x;
x=y;
y=temp-(a/b)*y;
return ans;
}
int main()
{
long long x,y,m,n,l;
while(scanf("%lld%lld%lld%lld%lld",&x,&y,&m,&n,&l)!=EOF)///输入的时候采用lld输入
{
long long ar,br;
long long g=exgcd(n-m,l,ar,br);
if((x-y)%g||m==n)
cout<<"Impossible"<<endl;
else
{
long long s=l/g;
ar=ar*(x-y)/g;
ar=(ar%s+s)%s;
cout<<ar<<endl;
}
}
return 0;
}
例题二 五指山(nefu 84)
有多组测试数据。
第一行是一个正整数T,表示测试数据的组数。
每组测试数据包括一行,四个非负整数,n(2 < n < 10^9),表示如来手掌圆圈的长度;d(0 < d < n),筋斗所能飞的距离;x(0 <= x < n),大圣的初始位置;
y(0 <= y < n),大圣想去的地方。
注意孙悟空的筋斗云只沿着逆时针方向翻。
分析:一个点运动,一个点静止,最终两个点重合
#include<cstdio>
#include<iostream>
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,x,y);
long long temp=x;
x=y;
y=temp-(a/b)*y;
return ans;
}
int main()
{
long long n,d,x,y;
int t;
cin>>t;
while(t--)
{
scanf("%lld%lld%lld%lld",&n,&d,&x,&y);
long long ar,br;
long long g=exgcd(d,n,ar,br);
if((y-x)%g!=0)
cout<<"Impossible"<<endl;
else
{
long long s=n/g;
ar=ar*(y-x)/g;
ar=(ar%s+s)%s;
cout<<ar<<endl;
}
}
return 0;
}