您的位置:首页 > 其它

bzoj [Noi2002]Savage 扩展欧几里得

2017-08-12 16:22 232 查看
枚举m,n^2判断

对于野人i,j,(H[i]+x*S[i])%m==(H[j]+x*S[j])%m,且x<=O[i]&&x<=O[j],他们才有可能相遇

化简得:(S[i]-S[j])*x+y*m=C[j]-C[i],扩欧解x最小值,判断

#include<cstdio>
#include<cstring>
#include<iostream>
#include<algorithm>
#include<cmath>
#define N 18
using namespace std;
int H
,S
,O
,n,m,X,Y;
bool bo;
int exgcd(int a,int b,int &x,int &y){
if(b==0){
x=1;y=0;
return a;
}
int gcd=exgcd(b,a%b,x,y);
int t=x;
x=y;
y=t-(a/b)*x;
return gcd;
}
bool judge(int x,int y,int mm){
//printf("%d  %d  %d\n",x,y,mm);
if(S[x]<S[y]) swap(x,y);
int a=S[x]-S[y],b=mm,c=H[y]-H[x];
int d=exgcd(a,b,X,Y);
if(c%d!=0) return 0;
X*=c/d;
int bd=b/d;
X=((X%bd)+bd)%bd;
if(X<=O[x]&&X<=O[y]) return 1;
return 0;
}
int main(){
scanf("%d",&n);
for(int i=1;i<=n;i++){
scanf("%d%d%d",&H[i],&S[i],&O[i]);
m=max(m,H[i]); H[i]--;
}
for(;;m++){
bo=0;
for(int i=1;i<=n;i++){
for(int j=i+1;j<=n;j++)
if(judge(i,j,m)){bo=1;break;}
if(bo==1)break;
}if(bo==0)break;
}
printf("%d\n",m);
return 0;
}
内容来自用户分享和网络整理,不保证内容的准确性,如有侵权内容,可联系管理员处理 点击这里给我发消息
标签: