题目描述
输入
输出
样例输入
3
1 3 4
2 7 3
3 2 1
样例输出
6
题解
因为岛是环形的,自然要 mod m
考虑两个野人 i,j,如果他们同时出现在一个山洞,那么 Ci+x*Pi=Cj+x*Pj(mod m), 移项后可得(Pi-Pj)*x+m*y=Cj-Ci
把 Pi-Pj 看成 a,m 看成 b,Cj-Ci 看成 c,可以得到方程 ax+by=c,容易想到用拓展欧几里得求解
因为两个野人是不能在同一个洞里,要么就是方程无解,要么就是方程的解 x>min(Li,Lj)
因为 n<=15, 我们可以枚举 m>=max(Ci) 的情况,暴力判断野人 i,j 是否符合要求,这样子时间复杂度就是 O(n^2*m)
代码
#include <iostream>
#include <cstdio>
#include <cstring>
#include <algorithm>
#include <cmath>
using namespace std;
int c[20],p[20],l[20],n,max1;
int gcd(int a,int b){return !b?a:gcd(b,a%b);}
void exgcd(int a,int b,int &x,int &y){
if(b==0){x=1,y=0;return;}
exgcd(b,a%b,x,y);
int k=x;
x=y;y=k-a/b*y;}
bool judge(int m){
int a,b,x,y,k,t;
for(int i=1;i<=n;i++)
for(int j=i+1;j<=n;j++){
a=p[i]-p[j],b=m,k=c[j]-c[i];
t=gcd(a,b);
if(k%t==0){
a/=t;b/=t;k/=t;
exgcd(a,b,x,y);
b=abs(b);
x=((k*x)%b+b)%b;
if(x<=min(l[i],l[j])) return 0;}
}
return 1;}
int main(){
cin>>n;
for(int i=1;i<=n;i++)
scanf("%d%d%d",&c[i],&p[i],&l[i]),max1=max(max1,c[i]);
for(int i=max1;i;i++)
if(judge(i)){
cout<<i<<endl;
return 0;}
}