这题分两种情况:
1.如果存在两个区间重叠,一定满足条件。
2.如果不存在两个区间重叠,那么id%x1=a,id%x2=b,a,b分别在[y1,z1],和[y2,z2]这两个区间内。
id=x1*s+a=x2*t+b;
x1*s+x2*t=a-b;
所以只要判断这个方程有解即可。
gcd(x1,x2)=x1*s+x2*t;
只要(a-b)%gcd(x1,x2)==0即可,求出(a-b)的范围,问题就等价于gcd(x1,x2)或者gcd(x1,x2)的倍数在范围内即可。
代码:
#include<iostream>
#include<cstdio>
#include<algorithm>
#define maxn 1005
using namespace std;
int n;
inline int rd(int &x)
{
char c=getchar();
while(!isdigit(c))c=getchar();
x=0;
while(isdigit(c))
{
x=x*10+c-'0';
c=getchar();
}
return x;
}
struct node
{
int x,y,z;
} a[maxn];
bool cmp(node x1,node x2)
{
if(x1.y==x2.y) return x1.z<x2.z;
else
return x1.y<x2.y;
}
int gcd(int a,int b)
{
if(!b) return a;
else return gcd(b,a%b);
}
int main()
{
while(scanf("%d",&n)!=EOF)
{
for(int i=0; i<n; i++)
{
rd(a[i].x);rd(a[i].y);rd(a[i].z);
// scanf("%d%d%d",&a[i].x,&a[i].y,&a[i].z);
}
if(n<=1)
{
printf("Can Take off\n");
continue;
}
sort(a,a+n,cmp);
// for(int i=0;i<n;i++)
// {
// cout<<a[i].x<<' '<<a[i].y<<' '<<a[i].z<<endl;
// }
int flag=0;
for(int i=0; i<n-1; i++)
{
int l1=a[i].y,r1=a[i].z,l2=a[i+1].y,r2=a[i+1].z;
int x1=a[i].x,x2=a[i+1].x;
if(l2<=r1)
{
flag=1;
break;
}
}
if(flag==1)
{
printf("Cannot Take off\n");
continue;
}
for(int i=0;i<n-1;i++)
{
for(int j=i+1;j<n;j++)
{
int l1=a[i].y,r1=a[i].z,l2=a[j].y,r2=a[j].z;
int x1=a[i].x,x2=a[j].x;
int Max=r2-l1,Min=l2-r1;
int d=gcd(x1,x2);
if((Min<=d&&d<=Max)||d<=(Max-Min+1))
{
flag=1;
break;
}
}
if(flag==1)
{
break;
}
}
if(flag==1)
{
printf("Cannot Take off\n");
}
else
{
printf("Can Take off\n");
}
}
return 0;
}