Yet another end of the world

Time Limit: 6000/3000 MS (Java/Others)    Memory Limit: 65535/32768 K (Java/Others)
Total Submission(s): 503    Accepted Submission(s): 152


Problem Description
In the year 3013, it has been 1000 years since the previous predicted rapture. However, the Maya will not play a joke any more and the Rapture finally comes in. Fortunately people have already found out habitable planets, and made enough airships to convey all the human beings in the world. A large amount of airships are flying away the earth. People all bear to watch as this planet on which they have lived for millions of years. Nonetheless, scientists are worrying about anther problem…
As we know that long distance space travels are realized through the wormholes, which are given birth by the distortion of the energy fields in space. Airships will be driven into the wormholes to reach the other side of the universe by the suction devices placed in advance. Each wormhole has its configured attract parameters, X, Y or Z. When the value of ID%X is in [Y,Z], this spaceship will be sucked into the wormhole by the huge attraction. However, the spaceship would be tear into piece if its ID meets the attract parameters of two wormholes or more at the same time.
All the parameters are carefully adjusted initially, but some conservative, who treat the Rapture as a grain of truth and who are reluctant to abandon the treasure, combine with some evil scientists and disrupt the parameters. As a consequence, before the spaceships fly into gravity range, we should know whether the great tragedy would happen or not. Now the mission is on you.
 

Input
Multiple test cases, ends with EOF.
In each case, the first line contains an integer N(N<=1000), which means the number of the wormholes.
Then comes N lines, each line contains three integers X,Y,Z(0<=Y<=Z<X<2*109).
 

Output
If there exists danger, output “Cannot Take off”, else output “Can Take off”.
 

Sample Input
2
7 2 3
7 5 6
2
7 2 2
9 2 2
 

Sample Output
Can Take off
Cannot Take off

题意:本题的题目讲的不是特别清楚- -|||或者是我的理解能力不够,我一直以为这个ID是固定的序列,但这题的ID是随机的,即只要有一个ID被两个虫洞以上盯上,就得输出Cannot Take off了。若不存在ID可能被两个虫洞或以上顶上,就输出Can Take off。

解题思路:N只有1000,故枚举两个两个点可以接受。我们要做的就是关于这两个虫洞,是否存在ID同时被吸进去。

我们观察这个式子:ID=a*Xi+b(Yi=<b<=Zi)=c*Xj+d(Yj=<d<=Zj) 其中abcd均为整数。

这是一个不定方程,该不定方程成立的条件为(b-d)整除gcd(Xi,Yi)(最大公约数)。(b-d)的范围可以求出来,应判断在某个区间之内是否有整除gcd(Xi,Yi)的数。至此,本题就解决了。

我的代码:

#include<iostream>
#include<stdio.h>
using namespace std;
#define N 1010
int x[N],y[N],z[N];
int n;
int gcd(int a, int b)
{
    if(b == 0) return a;
    return gcd(b, a%b);
}
bool chu(int i1,int j1)
{
   int c=gcd(x[i1],x[j1]);
   int a1,b1,a2,b2;
   int c1,d1,c2,d2;
   if(z[j1]>z[i1]) { b2=z[j1]; a2=y[j1];//我的判断区间是否有整除gcd的数的方法过于复杂,若有更好的方法请指教。
                     b1=z[i1]; a1=y[i1]; }
   else         { b2=z[i1]; a2=y[i1];
                     b1=z[j1]; a1=y[j1]; }
   c1=b2-b1; d1=b2-a1;
   c2=a2-b1; d2=a2-a1;
   bool f1=0;
   if(c1+c-c1%c<=d1 || c1%c==0) f1=1;
   if(d2>0)
   {
      if(c2<0) c2=0;
   if(c2+c-c2%c<=d2 || c2%c==0) f1=1;  
   }
   return f1;
}
int main()
{
    int i,j,k;
 
 while(scanf("%d",&n)!=EOF)
 {
  for(i=1;i<=n;i++)
      cin>>x[i]>>y[i]>>z[i];
        bool f1=0;
        for(i=1;i<=n;i++)
          for(j=i+1;j<=n;j++)
            if(chu(i,j)==1)
            {
             f1=1;
             break;
            }
        if(f1) printf("Cannot Take off\n");
        else   printf("Can Take off\n");
 }
 
  
 return 0;
}