[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 }