标签:pre gcd att als 相减 ace end string std
题意:给定一系列的虫洞,每个虫洞都有自己的x,y,z,当你的 id 对 x 取余后结果落在[ y,z ]区间内,则会被吸引,被两个或两个以上的虫洞吸引会有危险,求能否宇宙飞船能否起飞。
枚举每两个虫洞,有
id - k1 * x1 = u
id - k2 * x2 = v
其中k1与k2分别为 id / x1 与 id / x2,u与v分别为求余后的结果。
两式相减得 k2 * x2 - k1 * x1 = u - v
根据扩展欧几里得,判断 u - v 的取值是否能取到 gcd(x1, x2) 的整数倍即可
而 u 的范围为 [ y1, z1 ] ,v 的范围为 [ y2, z2 ],则 u - v 的范围为 [ y1 - z2,z1 - y2 ]。
假设范围为[ a,b ],gcd为 t 。
1、若a%t == 0 || b % t == 0,那么符合条件;
2、排除掉1的情况下,若a / t != b / t,那么也符合条件,因为若满足,则a与b中必定存在至少一个数能够对 t 取余为0。
#include<cstdio> #include<cstring> #include<cctype> #include<cstdlib> #include<cmath> #include<iostream> #include<sstream> #include<iterator> #include<algorithm> #include<string> #include<vector> #include<set> #include<map> #include<deque> #include<queue> #include<stack> #include<list> typedef long long ll; typedef unsigned long long llu; const int MAXN = 100 + 10; const int MAXT = 1000 + 10; const int INF = 0x7f7f7f7f; const double pi = acos(-1.0); const double EPS = 1e-6; using namespace std; ll gcd(ll m, ll n){ if(n == 0) return m; return gcd(n, m % n); } ll a, b, x[MAXT], y[MAXT], z[MAXT]; int n; inline bool is_attract(ll t, ll u, ll v){ if(u % t == 0 || v % t == 0) return true; return u / t != v / t; } bool solve(){ for(int i = 0; i < n; ++i) for(int j = i + 1; j < n; ++j){ ll t = gcd(x[i], x[j]); if(is_attract(t, y[j] - z[i], z[j] - y[i])) return false; } return true; } int main(){ while(scanf("%d", &n) == 1){ for(int i = 0; i < n; ++i) scanf("%I64d%I64d%I64d", x + i, y + i, z + i); if(solve()) printf("Can Take off\n"); else printf("Cannot Take off\n"); } return 0; }
HDU 4596 - Yet another end of the world(扩展欧几里得)
标签:pre gcd att als 相减 ace end string std
原文地址:http://www.cnblogs.com/tyty-TianTengtt/p/5996024.html