题解
- 容易得到c[i]+p[i]*x≡c[j]+p[j]*x(mod m)
- 化简得(p[i]-p[j])*x-my=c[j]-c[i]
-
p[i]-p[j]发现野人i每次跑的距离可以比野人j的少
-
所以b可能为负数
-
然后你将b取个abs
- 求出x后再判断是否小于等于l[i]或l[j]
代码
1 #include<cstdio> 2 #include<iostream> 3 #include<algorithm> 4 #include<cmath> 5 #include<cstring> 6 using namespace std; 7 int n,c[20],p[20],l[20],mx,x,y,k; 8 int gcd(int a,int b) { return b==0?a:gcd(b,a%b); } 9 void exgcd(int a,int b,int &x,int &y) 10 { 11 if(b==0) { x=1; y=0; return;} 12 exgcd(b,a%b,x,y); 13 int t=x; 14 x=y; y=t-a/b*y; 15 } 16 bool check(int m) 17 { 18 for (int i=1;i<=n;i++) 19 for (int j=i+1;j<=n;j++) 20 { 21 int a=p[i]-p[j],b=m,c1=c[j]-c[i],d=gcd(a,b),x,y; 22 if (c1%d==0) 23 { 24 a/=d; b/=d; c1/=d; 25 exgcd(a,b,x,y); 26 b=abs(b); 27 x=((x*c1)%b+b)%b; 28 while (!x) x+=b; 29 if (x<=min(l[i],l[j])) return false; 30 } 31 } 32 return true; 33 } 34 int main() 35 { 36 scanf("%d",&n); 37 for (int i=1;i<=n;i++) 38 { 39 scanf("%d%d%d",&c[i],&p[i],&l[i]); 40 mx=max(c[i],mx); 41 } 42 while (!check(mx)) mx++; 43 printf("%d ",mx); 44 return 0; 45 }