向量
描述
给你一对数a,b,你可以任意使用 (a,b),(a,−b),(−a,b),(−a,−b),(b,a),(b,−a),(−b,a),(−b,−a) ( a , b ) , ( a , − b ) , ( − a , b ) , ( − a , − b ) , ( b , a ) , ( b , − a ) , ( − b , a ) , ( − b , − a ) 这些向量,问你能不能拼出另一个向量 (x,y) ( x , y ) 。
说明:这里的拼就是使得你选出的向量之和为 (x,y) ( x , y )
Input
第一行数组组数 t,(t<=50000) t , ( t <= 50000 )
接下来t行每行四个整数 a,b,x,y(−2∗109<=a,b,x,y<=2∗109) a , b , x , y ( − 2 ∗ 10 9 <= a , b , x , y <= 2 ∗ 10 9 )
Output
t t 行每行为Y或者为N,分别表示可以拼出来,不能拼出来
Sample Input
3
2 1 3 3
1 1 0 1
1 0 -2 3
Sample Output
Y
N
Y
样例解释:
第一组:(2,1)+(1,2)=(3,3)
第三组:(-1,0)+(-1,0)+(0,1)+(0,1)+(0,1)=(-2,3)
问题分析
通过观察就可以发现上述向量可以归类成四个操作
1.
2.
y+=2b,y+0
y
+
=
2
b
,
y
+
0
3.
x+a,y+b
x
+
a
,
y
+
b
4.
x+b,y+a
x
+
b
,
y
+
a
然后
3
3
和最多只会用到一次,因为两次就会回到
1
1
和的状态。所以我们去枚举操作
3
3
和套裴蜀定理就可以了。
k1⋅(a,b)+k2(b,a)=(x,y)
k
1
⋅
(
a
,
b
)
+
k
2
(
b
,
a
)
=
(
x
,
y
)
1.
k1⋅a+k2⋅b=x
k
1
⋅
a
+
k
2
⋅
b
=
x
2.
k1⋅b+k2⋅a=y
k
1
⋅
b
+
k
2
⋅
a
=
y
这里
1
1
和的
k1
k
1
与
k2
k
2
并不一定相等,但是我们可以肯定至少奇偶性是相同的,
因此套用裴蜀定理,判断 x x 和是否能同时整除 gcd(a,b) g c d ( a , b ) 即可。
using namespace std;
long long gcd(long long a,long long b)
{
return b==0?a:gcd(b,a%b);
}
bool love(long long x,long long y,long long g)
{
return x%g==0&&y%g==0;
}
int main()
{
long long t,a,b,x,y;
for(scanf("%lld",&t); t; t--) {
scanf("%lld%lld%lld%lld", &a, &b, &x, &y);
long long g = gcd(2 * a, 2 * b);
if (love(x, y, g) || love(x + a, y + b, g) || love(x + b, y + a, g) || love(x + a + b, y + a + b, g))
puts("Y");
else
puts("N");
}
return 0;
}