CodeForce-101C Vector题解
题面
At a geometry lesson Gerald was given a task: to get vector B out of vector A. Besides, the teacher permitted him to perform the following operations with vector A:
Turn the vector by 90 degrees clockwise.
Add to the vector a certain vector C.
Operations could be performed in any order any number of times.
Can Gerald cope with the task?
Input
The first line contains integers x1 , y1 − the coordinates of the vector A (-108≤x1,y1≤108). The second and the third line contain in the similar manner vectors B and C (their coordinates are integers; their absolute value does not exceed 108).
Output
Print “YES” (without the quotes) if it is possible to get vector B using the given operations. Otherwise print “NO” (without the quotes).
这是个数学推导题,具体的直接看代码里的注释吧~~~
/*
* 向量A可以执行两个操作:
* 1. 旋转90°
* 2. 加上向量C
* 问最后是否能够得到向量B
*
* 思路:
* 以^X表示X旋转90°,假设依次执行操作为:1212,即
* ^(^A+C) + C
* 这个式子显然可以写成^^A + ^C + C
* 不难发现,无论怎么操作,都可以理解成 A旋转n次 + a C + b ^C + c ^^C + d ^^^C
* 显然A旋转n次实际上只会有三种情况{0,1,2, 3},设B-A旋转n次为E(E有四种情况)
* 那么现在问题就是 a C + b ^C + c ^^C + d ^^^C = E在C,^C,^^C,^^^C,E都已知的情况下是否有非负整数解(a,b,c,d)
* 设C(x, y),E(m, n)
* 则 ^C(y, -x), ^^C(-x, -y), ^^^C(-y, x)
* 于是:
* a(x, y) + b(y, -x) + c(-x, -y) + d(-y, x) = (m, n)
* 即:
* ax + by - cx - dy = m (1)
* ay - bx - cy + dx = n (2)
* 求这个方程组是否有非负整数解即可(a,b,c,d是未知数,x,y,m,n是已知的)
* (1)式*y,(2)式*x,两式相减得到:(x*x + y*y)b - (x*x + y*y) d = my - nx
* 即 b - d = (my-nx) / (x*x+y*y) (3)
* (1)式*x, (2)式*y,两式相加得到:(x*x + y*y)a - (x*x + y*y) c = mx + ny
* 即 a - c = (mx+ny) / (x*x+y*y) (4)
* (3)和(4)有非负整数解的前提即有整数解的前提是 (my-nx) | (x*x+y*y)且(mx+ny) | (x*x+y*y)
* 而容易知道,(3)(4)有整数解时,(1)(2)式必定成立
* 所以判断条件就是:(my-nx) | (x*x+y*y)且(mx+ny) | (x*x+y*y)是否成立
*/
#include<iostream>
#define ll long long
using namespace std;
int main()
{
#ifdef AFei
freopen("in.txt", "r", stdin);
#endif
int x1, y1, x2, y2, x, y;
scanf("%d%d%d%d%d%d", &x1, &y1, &x2, &y2, &x, &y);
ll DIV = 1LL * x * x + 1LL * y * y;
ll m, n;
// 当A旋转次数 mod 4 == 0时
m = x2 - x1, n = y2 - y1;
bool flag0 = !((m*y-n*x) % DIV || (m*x+n*y) % DIV);
// 当A旋转次数 mod 4 == 1时
m = x2 - y1, n = y2 + x1;
bool flag1 = !((m*y-n*x) % DIV || (m*x+n*y) % DIV);
// 当A旋转次数 mod 4 == 2时
m = x2 + x1, n = y2 + y1;
bool flag2 = !((m*y-n*x) % DIV || (m*x+n*y) % DIV);
// 当A旋转次数 mod 4 == 3时
m = x2 + y1, n = y2 - x1;
bool flag3 = !((m*y-n*x) % DIV || (m*x+n*y) % DIV);
printf(flag0 || flag1 || flag2 || flag3 ? "YES\n" : "NO\n");
return 0;
}