[haoi2011]向量
给你一对数a,b,你可以任意使用(a,b), (a,-b), (-a,b), (-a,-b), (b,a), (b,-a), (-b,a), (-b,-a)这些向量,问你能不能拼出另一个向量(x,y)。
说明:这里的拼就是使得你选出的向量之和为(x,y)
题解:
首先这八个向量是不必都用上的,去除那些加负号后等同的向量后剩下了四个(a,b)(a,-b)(b,a)(b,-a)。
最后要组成的向量是(x,y),由向量运算法则设这样的式子:
(x,y)=A(a,b)+B(a,-b)+C(b,a)+D(b,-a);
可化成:
x=a(A+B)+b(C+D)
y=b(A-B)+a(C-D)
设x1=A+B,y1=C+D,x2=A-B,y2=C-D;
x=ax1+by1;
y=bx2+ay2;
然后我们就可以看出来了,如果A,B,C,D有解,
那么x1+x2,y1+y2都是偶数;
然后利用拓展gcd求出一组x1,y1,x2,y2,
判断一下即可;
细节上主要注意直接求出的一组解可能不符条件,但变形后就符合条件了
由于判断的是奇偶,每个方程的解最多两种情况,乘起来一共四种情况,都需要判断;
详见代码
#include<iostream> #include<cstdio> #include<cstring> #include<string> #include<ctime> #include<algorithm> #include<cstdlib> #include<map> #include<set> #include<vector> #include<queue> #include<cmath> using namespace std; #define FILE "dealing" #define LL long long #define up(i,j,n) for(int i=j;i<=n;i++) #define pii pair<LL,LL> #define piii pair<LL,pair<LL,LL> > template<typename T> inline bool chkmin(T &a,T b){return a>b?a=b,true:false;} template<typename T> inline bool chkmax(T &a,T b){return a<b?a=b,true:false;} namespace IO{ char *fs,*ft,buf[1<<15]; inline char gc(){return (fs==ft&&(ft=(fs=buf)+fread(buf,1,1<<15,stdin),fs==ft))?0:*fs++;} inline int read(){ LL x=0;int ch=gc();bool f=0; while(ch<'0'||ch>'9'){if(ch=='-')f=1;ch=gc();} while(ch<='9'&&ch>='0'){x=(x<<1)+(x<<3)+ch-'0';ch=gc();} return f?-x:x; } }using namespace IO; LL a,b,x,y,t; namespace OI{ void gcd(LL a,LL b,LL& d,LL &x,LL &y){ if(!b){d=a,x=1,y=0;return;} gcd(b,a%b,d,x,y); LL t=x; x=y; y=t-a/b*x; } char check(){ LL d,x1,y1,x2,y2; gcd(a,b,d,x1,y1); x2=y1,y2=x1; a/=d,b/=d; if(x%d||y%d)return 'N'; x1*=x/d,y1*=x/d,x2*=y/d,y2*=y/d; if(!((x1+x2)&1)&&!((y1+y2)&1))return 'Y'; x1+=b,y1-=a; if(!((x1+x2)&1)&&!((y1+y2)&1))return 'Y'; x2+=a,y2-=b; if(!((x1+x2)&1)&&!((y1+y2)&1))return 'Y'; x1+=b,y1-=a; if(!((x1+x2)&1)&&!((y1+y2)&1))return 'Y'; return 'N'; } void slove(){ t=read(); while(t--){ a=read(),b=read(),x=read(),y=read(); printf("%c\n",check()); } } } int main(){ freopen(FILE".in","r",stdin); freopen(FILE".out","w",stdout); using namespace OI; slove(); return 0; }