(扩展欧几里德算法)zzuoj 10402: C.机器人
10402: C.机器人
Description Dr. Kong 设计的机器人卡尔非常活泼,既能原地蹦,又能跳远。由于受软硬件设计所限,机器人卡尔只能定点跳远。若机器人站在(X,Y)位置,它可以原地蹦,但只可以在(X,Y),(X,-Y),(-X,Y),(-X,-Y),(Y,X),(Y,-X),(-Y,X),(-Y,-X)八个点跳来跳去。 现在,Dr. Kong想在机器人卡尔身上设计一个计数器,记录它蹦蹦跳跳的数字变化(S,T),即,路过的位置坐标值之和。 你能帮助Dr. Kong判断机器人能否蹦蹦跳跳,拼出数字(S,T)吗? 假设机器人卡尔初始站在(0,0)位置上。 Input 第一行: K 表示有多少组测试数据。 接下来有K行,每行:X Y S T 1≤K≤10000 -2*109 <= X , Y, S, T <= 2*109 数据之间有一个空格。 Output 对于每组测试数据,输出一行:Y或者为N,分别表示可以拼出来,不能拼出来 Sample Input 3 2 1 3 3 1 1 0 1 1 0 -2 3 Sample Output Y N Y
欧几里德与扩展欧几里德算法 :http://www.cnblogs.com/frog112111/archive/2012/08/19/2646012.html
/*
思路:(X,Y),(X,-Y),(-X,Y),(-X,-Y),(Y,X),(Y,-X),(-Y,X),(-Y,-X)
虽然八个点,其实有用的只有四个点,其他的四个点都可以被替代,比如
(x,y)可以替代 (-x, -y) <-> -[(x, y)]
设这四个点是(x,y), (x, -y), (y, x), (y,-x)分别经过a1, a2, a3, a4次
则有
(a1+a2)x + (a3+a4)y = s; ---> Ax + By = s; (很明显的不定方程的形式)
(a1-a2)y + (a3-a4)x = t; ---> Dx + Cy = t;
仔细观察上述式子, A+D 和 B+C 都是 偶数
对于Ax + By = s,可以利用exgcd()求出A, B的值,同理也可以求出D,C的值
如果A,B 为等式的解,那么其余的结为:
A = A + y/gcd(A, B)*t(其中t为任意整数)
B = B + x/gcd(A, B)*t
利用上面的式子, 枚举 A,B,C,D ,知道 满足 A+D 和 B+C的结果为偶数!
*/
1 #include<iostream> 2 #include<cstring> 3 #include<cstdio> 4 #include<algorithm> 5 #include<vector> 6 #include<map> 7 #include<queue> 8 #define MAX 0x3f3f3f3f 9 #define N 550 10 using namespace std; 11 12 long long exgcd(long long a,long long b,long long &x,long long &y) 13 { 14 if(b==0) 15 { 16 x=1; 17 y=0; 18 return a; 19 } 20 long long r=exgcd(b,a%b,x,y); 21 long long t=x; 22 x=y; 23 y=t-a/b*y; 24 return r; 25 } 26 27 /* 28 x = x + b/gcd(a, b)*t; 29 y = y - a/gcd(a, b)*t; 30 */ 31 32 int main() { 33 int k; 34 long long x, y, s, t; 35 scanf("%d", &k); 36 while(k--){ 37 scanf("%lld%lld%lld%lld", &x, &y, &s, &t); 38 long long a, b, c, d, g; 39 g = exgcd(x, y, a, b); 40 c = a; 41 d = b; 42 if(s%g==0 && t%g==0){ 43 a = a*(s/g); 44 b = b*(s/g); 45 c = c*(t/g); 46 d = d*(t/g); 47 bool flag = false; 48 for(int i=-2; i<=2 && !flag; ++i){ 49 long long aa, bb; 50 aa = a+x/g*i; 51 bb = b-y/g*i; 52 for(int j=-2; j<=2 && !flag; ++j){ 53 long long cc, dd; 54 cc = c+x/g*j; 55 dd = d-y/g*j; 56 if((aa+dd)%2==0 && (bb+cc)%2==0) 57 flag = true; 58 } 59 } 60 if(flag) printf("Y\n"); 61 else printf("N\n"); 62 } else { 63 printf("N\n") ; 64 } 65 } 66 return 0; 67 }
本文来自博客园,作者:hjzqyx,转载请注明原文链接:https://www.cnblogs.com/hujunzheng/p/4483343.html