拓展欧几里得入门题
两个野人若要走到同一个洞穴,设他们走了x步,则p[i]*x+c[i]≡p[j]*x+c[j](mod ans),ans即答案;
移项得到(p[i]-p[j])*X+ansY=c[j]-c[i];
即aX+bY+=C的形式,枚举ans,n^2的枚举每一个野人,用ex_gcd求得最小解,看X是否在他们的生命时间内。
/**************************************************************
Problem: 1407
User: xrdog
Language: C++
Result: Accepted
Time:3056 ms
Memory:1292 kb
****************************************************************/ #include<iostream>
#include<cstdio>
#include<algorithm>
#include<cstdlib>
#include<algorithm>
#include<vector>
#include<cmath>
#include<ctime>
#include<cstring>
#define yyj(s) freopen(s".in","r",stdin),freopen(s".out","w",stdout);
#define llg long long
using namespace std; struct node
{
llg c,p,l;
}a[];
llg i,j,k,n,m,w,x,y,aa,ans,bb,cc;
bool f; void ex_gcd(const llg a,const llg b,llg &x,llg &y)
{
if (!b)
{
x=,y=;
return ;
}
ex_gcd(b,a%b,x,y);
llg temp=x;
x=y;
y=temp-a/b*y;
} llg gcd(llg a,llg b){return b==?a:gcd(b,a%b);} int main()
{
// yyj("savage");
cin>>n;
for (i=;i<=n;i++) scanf("%lld%lld%lld",&a[i].c,&a[i].p,&a[i].l);
for (ans=;ans<=;ans++)
{
f=true;
for (i=;i<n;i++)
if (f)
for (j=i+;j<=n;j++)
{
aa=a[i].p-a[j].p; bb=ans; cc=a[j].c-a[i].c;
//if (!(aa>=0 && cc>=0)) continue;
w=gcd(aa,bb);
x=,y=;
if (cc%w) continue;
ex_gcd(aa/w,bb/w,x,y);
x=(x*(cc/w)) % (bb/w);
if (x<) x+=abs(bb/w);
if (x<=min(a[i].l,a[j].l)) {f=false; break;}
}
if (f)
{
if (ans==) ans=;
cout<<ans;
return ;
}
}
return ;
}