HDU 4596 Yet another end of the world (扩展欧几里德)

Yet another end of the world

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


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*10 9).
 

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
 

首先题目简单意思就是求  如果某个数字模Xi Xj 同时处于两个区间就会被撕裂 不能takeoff


第一点 由于X>Z>=Y 那么如果存在两个区间相交 那么必然不能takeoff - - 因为一定有一个数会模完落在相交的区间内

其他枚举出两组x,y,z。
然后判断这两组是否能找到一个d,使得满足题目条件。

现在假设a、b,有a*x1+y1≤d≤a*x1+z1和b*x2+y2≤d≤b*x2+z2;
若两段区间有交集,必有a*x1+y1≤b*x2+z2且b*x2+y2≤a*x1+z1;
化简得a*x1-b*x2≤z2-y1 且a*x1-b*x2≥y2-z1;
若a,b有整数解,根据拓展欧几里得定理ax1+bx2=u有整数解的情况为u%gcd(x1,x2)==0;
所以若存在y2-z1≤u≤z2-y1,使得u%gcd(x1,x2)==0即可。

对于这个有整数解的情况 是在区间找到一个数是这个gcd的倍数就有整数解

AC代码如下:
//
//  Created by TaoSama on 2015-05-11
//  Copyright (c) 2015 TaoSama. All rights reserved.
//
#include <algorithm>
#include <cctype>
#include <cmath>
#include <cstdio>
#include <cstdlib>
#include <cstring>
#include <iomanip>
#include <iostream>
#include <map>
#include <queue>
#include <string>
#include <set>
#include <vector>

using namespace std;
const int INF = 0x3f3f3f3f;
const int MOD = 1e9 + 7;
const int N = 1e5 + 10;

int n, x[1005], y[1005], z[1005];

bool judge(int gcd, int a, int b) {
    if(a % gcd == 0 || b % gcd == 0) return true; //边界满足
    if(a < 0 && b > 0) return true;
    //本身区间相交 必然不能takeoff
    if(b / gcd - a / gcd > 0) return true; //跨过一个gcd的倍数
    return false;
}

bool solve() {
    for(int i = 1; i <= n; ++i) {
        for(int j = i + 1; j <= n; ++j) {
            int gcd = __gcd(x[i], x[j]);
            if(judge(gcd, y[j] - z[i], z[j] - y[i]))
                return false;
        }
    }
    return true;
}

int main() {
#ifdef LOCAL
    freopen("in.txt", "r", stdin);
//  freopen("out.txt","w",stdout);
#endif
    ios_base::sync_with_stdio(0);

    while(scanf("%d", &n) == 1) {
        for(int i = 1; i <= n; ++i)
            scanf("%d%d%d", x + i, y + i, z + i);

        puts(solve() ? "Can Take off" : "Cannot Take off");
    }
    return 0;
}


你可能感兴趣的:(HDU 4596 Yet another end of the world (扩展欧几里德))