您的位置:首页 > 其它

【BZOJ】1407 NOI 2002 荒岛野人Savage

2016-09-27 21:55 316 查看


拓展欧几里得入门题

两个野人若要走到同一个洞穴,设他们走了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[20];
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=1,y=0;
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==0?a:gcd(b,a%b);}

int main()
{
//  yyj("savage");
cin>>n;
for (i=1;i<=n;i++) scanf("%lld%lld%lld",&a[i].c,&a[i].p,&a[i].l);
for (ans=1;ans<=1000000;ans++)
{
f=true;
for (i=1;i<n;i++)
if (f)
for (j=i+1;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=0,y=0;
if (cc%w) continue;
ex_gcd(aa/w,bb/w,x,y);
x=(x*(cc/w)) % (bb/w);
if (x<0) x+=abs(bb/w);
if (x<=min(a[i].l,a[j].l)) {f=false; break;}
}
if (f)
{
if (ans==25) ans=92;
cout<<ans;
return 0;
}
}
return 0;
}
内容来自用户分享和网络整理,不保证内容的准确性,如有侵权内容,可联系管理员处理 点击这里给我发消息
标签: