看到数据范围其实就可以确定这是一道结论题。
首先分析,给定你的向量的两个坐标a,b有八种组合方式可以用,但实际上整理一下可以得出实际上只有五种,x/y ±2a,x/y ±2b,x+a,y+b,x+b,y+a,再就是什么都不做(废话。。。)
那么要想用a,b组合出x,y,那必须满足一下条件:
令A=2a,B=2b,d=gcd(A,B),存在i*a+j*b=x,u*a+v*b=y,并且d|x,d|y。
(根据裴蜀定理{若a,b是整数,且gcd(a,b)=d,那么对于任意的整数x,y,ax+by都一定是d的倍数,特别地,一定存在整数x,y,使ax+by=d成立})
那么只要下面四种情况的其中一种满足即可:
(x,y),(x+a,y+b),(x+b,y+a),(x+a+b,y+a+b)
代码如下:
#include<cstdio> #include<cstring> #include<cstdlib> #include<cmath> #include<iostream> #include<algorithm> using namespace std; typedef long long ll; ll T,d; inline ll gcd(ll a,ll b) {return b==0?a:gcd(b,a%b);} inline bool check(ll x,ll y) {return (x%d==0)&&(y%d==0);} int main() { scanf("%lld",&T); while(T--){ ll a,b,x,y; scanf("%lld%lld%lld%lld",&a,&b,&x,&y); d=gcd(a,b)<<1;a%=d,b%=d,x%=d,y%=d; if(check(x,y)||check(x+a,y+b)||check(x+b,y+a)||check(x+a+b,y+a+b)) printf("Y "); else printf("N "); } return 0; }