[HDOJ4596] Yet another end of the world(数学,gcd,二元一次方程)

题目链接:http://acm.hdu.edu.cn/showproblem.php?pid=4596

题意就是给n个xi,yi,zi,找出2组数,使得存在一个整数A,yi<=A%xi<=zi且yj<=A%xj<=zj。

 yi<=a<=zi

yj<=b<=zj

那么yi-zj<=a-b<=zi-yj,即判断gcd(xi, xj)的倍数是不是在这个范围里。

找一下这个倍数就行了。

 1 #include <bits/stdc++.h>
 2 using namespace std;
 3 
 4 const int maxn = 2222;
 5 int n;
 6 int x[maxn], y[maxn], z[maxn];
 7 
 8 int gcd(int m, int n) {
 9     while(m) {
10         int c = n % m;
11         n = m;
12         m = c;
13     }
14     return n;
15 }
16 
17 inline bool scan_d(int &num) {
18     char in;bool IsN=false;
19     in=getchar();
20     if(in==EOF) return false;
21     while(in!='-'&&(in<'0'||in>'9')) in=getchar();
22     if(in=='-'){ IsN=true;num=0;}
23     else num=in-'0';
24     while(in=getchar(),in>='0'&&in<='9'){
25         num*=10,num+=in-'0';
26     }
27     if(IsN) num=-num;
28     return true;
29 }
30 
31 bool ok(int l, int r, int x) {
32     if(l % x == 0 || r % x == 0) return 1;
33     if(r - l + 1 >= x) return 1;
34     if(l / x != r / x) return 1;
35     return 0;
36 }
37 
38 int main() {
39     // freopen("in", "r", stdin);
40     // freopen("out", "w", stdout);
41 
42     while(~scanf("%d", &n)) {
43         bool flag = 0;
44         for(int i = 0; i < n; i++) {
45             scan_d(x[i]); scan_d(y[i]); scan_d(z[i]);
46         }
47         for(int i = 0; i < n; i++) {
48             if(flag) break;
49             for(int j = i+1; j < n; j++) {
50                 if(flag) break;
51                 int g = gcd(x[i], x[j]);
52                 int l = abs(y[i] - z[j]), r = abs(y[j] - z[i]);
53                 if(l > r) swap(l, r);
54                 if(ok(l, r, g)) flag = 1;
55             }
56         }
57         if(!flag) printf("Can Take off\n");
58         else printf("Cannot Take off\n");
59     }
60     return 0;
61 }

 

posted @ 2017-05-01 20:19  Kirai  阅读(140)  评论(0编辑  收藏  举报