zzuoj 10402: C.机器人 【数论 exgcd】
来源:互联网 发布:stateserver 端口 编辑:程序博客网 时间:2024/06/05 18:01
10402: C.机器人
Time Limit: 2 Sec Memory Limit: 128 MBSubmit: 56 Solved: 21
[Submit][Status][Web Board]
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
思路:设num[i]为第i个位置路过的次数。
则有
(num[1]*x + num[2]*x - num[3]*x - num[4]*x + num[5]*y + num[6]*y - num[7]*y - num[8]*y) = s.
(num[1]*y - num[2]*y + num[3]*y - num[4]*y + num[5]*x - num[6]*x + num[7]*x - num[8]*y) = t.
变量太多,不好搞,考虑能否去掉几个 或者 将若干个变量表示为一个变量。
发现
num[1]*x - num[4]*x + ... = s
num[1]*y - num[4]*y + ... = t
可以合并(num[1]-num[4])为一个变量 cnt[1].
同理(x, -y) (-x, y) -> (num[2] - num[3]) = cnt[2].
(y, x) (-y, -x) -> (num[5] - num[8]) = cnt[3] .
(y, -x) (-y, x) -> (num[6] - num[7]) = cnt[4]。
那么直接有
cnt[1] * x + cnt[2] * x + cnt[3] * y + cnt[4] * y = s.
cnt[1] * y - cnt[2] * y + cnt[3] * x - cnt[4] * x = t.
化简有
(cnt[1]+cnt[2]) * x + (cnt[3]+cnt[4]) * y = s.
(cnt[1]-cnt[2]) * y + (cnt[3]-cnt[4]) * x = t.
可以用exgcd求出A = (cnt[1]+cnt[2]), B = (cnt[3]+cnt[4]), C = (cnt[1]-cnt[2]), D = (cnt[3]-cnt[4])。
条件——A + C 和 B + D是偶数。
求出通解A、B、C、D后,以A C举例,A0 = A + i * (y / gcd(x, y)), C0 = C - j * (x / gcd(x, y))。
我们考虑b-a*x奇偶性的判定,其中a、b是定值,x不定。x为偶数时,a*x一定是偶数。反之x为奇时就取决于定值x。
抛开不沾边的,就是说在若只考虑奇偶性,那么只需处理两种情况。x为偶数时处理0、x为奇数时处理1。
我们枚举i、j(0 <= i, j <= 1),看是否满足即可。
最后注意特判 x = 0, y = 0 的情况。
AC代码:
#include <iostream> #include <cstdio> #include <cstring> #include <cmath> #include <algorithm> #include <map> #include <string> #include <vector> #include <queue> #include <stack> #define CLR(a, b) memset(a, (b), sizeof(a)) #define ll o<<1 #define rr o<<1|1 using namespace std; typedef long long LL; const int MOD = 1e9+7; const int MAXN = 500+10; const int MAXM = 200000; const int INF = 0x3f3f3f3f; void add(LL &x, LL y) {x += y; x %= MOD;} void exgcd(LL a, LL b, LL &d, LL &x, LL &y) { if(b == 0) {d = a, x = 1, y = 0;} else { exgcd(b, a%b, d, y, x); y -= x * (a / b); } } int main() { int t; scanf("%d", &t); while(t--) { LL x, y, s, t; scanf("%lld%lld%lld%lld", &x, &y, &s, &t); if(x == 0 && y == 0) { if(s == 0 && t == 0) printf("Y\n"); else printf("N\n"); continue; } LL a, b, d; exgcd(x, y, d, a, b); if(s % d || t % d) { printf("N\n"); continue; } LL A, B, C, D; A = s / d * a; B = s / d * b; C = t / d * a; D = t / d * b; bool flag = false; LL AA, BB, CC, DD; for(int i = 0; i <= 1; i++) { AA = A + 1LL * i * (y / d); BB = B - 1LL * i * (x / d); for(int j = 0; j <= 1; j++) { CC = C - 1LL * j * (x / d), DD = D + 1LL * j * (y / d); //printf("%lld %lld %lld %lld\n", AA, BB, CC, DD); if((AA + CC) % 2 == 0 && (BB + DD) % 2 == 0) flag = true; if(flag) break; } if(flag) break; } printf(flag ? "Y\n" : "N\n"); } return 0; }
- zzuoj 10402: C.机器人 【数论 exgcd】
- [exgcd] zzu oj 10402 C.机器人
- CodeForces 7C Line Exgcd(数论)
- CodeForces 7C Line Exgcd(数论)
- 第七届河南省赛 zzuoj 10402: C.机器人 (拓展欧几里得) 好题
- 【模板】【数论】gcd和exgcd
- exgcd
- Exgcd
- exgcd
- exgcd
- EXGCD
- 数论专题小结:gcd算法与exgcd算法
- hihocoder 1297 数论四·扩展欧几里德(exgcd)
- [模板][数论][gcd+exgcd+sieve+power+euler_phi+euler_table+inv]
- 基础数论算法(2) GCD LCM EXGCD 学习笔记
- Poj 2115 C Looooops(exgcd变式)
- Codeforces 724C Ray Tracing(exgcd)
- 【数论】c
- sqlserver创建临时表
- 关于JPA方法名创建自动查询
- PCT-36.523
- 101.Examine the data in the PROMO_BEGIN_DATE column of the PROMOTIONS table:
- Hadoop 2.5.2分布式集群配置
- zzuoj 10402: C.机器人 【数论 exgcd】
- IDEA配置tomcat
- compile boost with -fPIC
- ios UISearchDisplayController 实现 UITableView 搜索功能
- dos命令行连接数据库 oracle11g
- Maven--搭建开发环境(一)
- libsvm 在matlab中保存读取model文件的接口
- hdu2544 最短路 Dijstra算法堆优化,Bellman-Ford,Bellman-Ford队列优化
- 阿里云ECS 下ngixn 配置详解