题意:
给你n个
xi
,
yi
,
zi
,让你判断是否存在一个数num, 满足形如下式的条件,满足的话则代表此飞船在这个虫洞的作用力下,那么这个num号飞船不能再同时再处于另一个冲动的引力下,否则会被潮汐力撕碎。。。现在问你是否有被撕碎的危险。
y<=num(modxi)<=z
思路:
遍历两两组合的全部。对于任意的两个有如下的特点。
nummodx1=r1(1)
nummodx2=r2(2)
即:
num=k1∗x1+r1=k2∗x2+r2
经过化简:
k1∗x1−k2∗x2=r2−r1(3)
(3)式是典型的二元一次不定方程,有解的充要条件是 gcd(k1,k2)|(r2−r1) 即:( r2 - r1 ) % gcd( k1 , k2 ) = 0
对于这两个区间来说,如果相交,那么必可选出相等的点使得 r2 - r1 =0,从而有解。但不相交的情况也有可能有解,我们假设在左边的那个区间为y1,z1,右边的为y2,z2,这时 r2 - r1 的取值范围就在 [y2−z1,z2−y1] 间了,我们这时只需判断这个区间里是否有模g = gcd( k1 , k2 )等于0的数就好了。
判断的方法:如果 y2−z1 % g 不为零并且 z2−y1 并没有超过g的循环节。具体代码如下:
代码:
#include <iostream>
#include <cstdio>
#include <string.h>
typedef long long int lli;
using namespace std;
lli flag = 0;
lli gcd(lli a,lli b){
return b == 0 ? a:gcd(b,a%b);
}
struct node{
lli x,y,z;
}a[1050];
bool f(int ii,int jj){
if( (a[ii].z >= a[jj].y && a[ii].y < a[jj].z)
|| (a[jj].z >= a[ii].y && a[jj].y < a[ii].z)){
return true;
}
if(a[ii].y > a[jj].z){
swap(ii,jj);
}
lli from = a[jj].y-a[ii].z;
lli to = a[jj].z-a[ii].y;
lli gc = gcd(a[ii].x,a[jj].x);
if(from % gc != 0 && to-from <= gc-from%gc-1){
return false;
}
return true;;
}
int main(){
int n;
while(~scanf("%d",&n)){
flag = 0;
for(int i = 1;i <= n;i++){
scanf("%lld%lld%lld",&a[i].x,&a[i].y,&a[i].z);
}
for(int i = 1; i< n;i++){
for(int j = i+1;j <= n;j++){
if(f(i,j)){
flag = 1;
break;
}
}
if(flag == 1) break;
}
if(flag == 0){
puts("Can Take off");
}
else
puts("Cannot Take off");
}
}