[haoi2011]向量
Posted Shadow
tags:
篇首语:本文由小常识网(cha138.com)小编为大家整理,主要介绍了[haoi2011]向量相关的知识,希望对你有一定的参考价值。
描述 Description
给你一对数a,b,你可以任意使用(a,b), (a,-b), (-a,b), (-a,-b), (b,a), (b,-a), (-b,a), (-b,-a)这些向量,问你能不能拼出另一个向量(x,y)。
说明:这里的拼就是使得你选出的向量之和为(x,y)
输入格式 Input Format
第一行数组组数t,(t<=50000)
接下来t行每行四个整数a,b,x,y (-2*10^9<=a,b,x,y<=2*10^9)
输出格式 Output Format
t行每行为 Y 或者为 N ,分别表示可以拼出来,不能拼出来
样例输入 Sample Input
3
2 1 3 3
1 1 0 1
1 0 -2 3
样例输出 Sample Output
Y
N
Y
时间限制 Time Limitation
1s
注释 Hint
样例解释:
第一组:(2,1)+(1,2)=(3,3)
第三组:(-1,0)+(-1,0)+(0,1)+(0,1)+(0,1)=(-2,3)
来源 Source
haoi2011
思路:这个题就是一个真正的数学题哇........题目中说道你可以任意使用(a,b), (a,-b), (-a,b), (-a,-b), (b,a), (b,-a), (-b,a), (-b,-a),看似有很多情况。其实你列下来可以得到一个方程。因为可以设(x,y)=A(a,b)+B(a,-b)+C(b,a)+D(b,-a);A,B,C,D这四个系数的式子就可以表示所有情况了//好好想一下。然后把这个式子拆成两个方程
①x=a(A+B)+b(C+D)
②y=a(C-D)+b(A+B);//去括号然后合并同类项,相信大家都会吧
然后要想使这个向量(a,b)变成(x,y)那么一定要满足这两个方程有解吧。所以先特判一下a=0或b=0这两种情况。然后求出gcd(a,b);因为要是这两个方程有解那么就一定要满足x%(gcd(a,b))==0和y%(gcd(a,b))==0这两个情况。然后你保证了方程①和②有解的情况下你并不能保证①+②有解。所以①加②就可以化为
③x+y=a(A+B)+b(C+D)+a(C-D)+b(A-B);
x+y=A(a+b)+B(a-b)+C(a+b)+D(b-a)
x+y=(A+C)*(a+b)+(B-D)*(a-b)
//这应该也是很好理解的吧
然后你只需保证这个方程有解即可,及为(x+y)%(a+b)==0&&(x+y)%(a-b)==0。那么这个向量(a,b),就可以变成(x,y);
代码如下:
1 #include<iostream> 2 #include<cstdio> 3 #include<cmath> 4 #include<algorithm> 5 #include<cstring> 6 #define ll long long 7 using namespace std; 8 inline ll read() 9 { 10 char ch=getchar(); 11 ll x=0,f=1; 12 while(ch>‘9‘||ch<‘0‘) 13 { 14 if(ch==‘-‘) 15 f=-1; 16 ch=getchar(); 17 } 18 while(ch>=‘0‘&&ch<=‘9‘) 19 { 20 x=x*10+ch-‘0‘; 21 ch=getchar(); 22 } 23 return x*f; 24 } 25 ll gcd(ll a,ll b) 26 {return b==0?a:gcd(b,a%b);} 27 int main() 28 { 29 int t=read(); 30 for(int i=1;i<=t;i++) 31 { 32 ll a=read(),b=read(),x=read(),y=read(); 33 a=abs(a);b=abs(b); 34 if(!a) 35 { 36 if(x%b==0&&y%b==0) 37 cout<<‘Y‘<<endl; 38 else 39 cout<<‘N‘<<endl; 40 } 41 else if(!b) 42 { 43 if(x%a==0&&y%a==0) 44 cout<<‘Y‘<<endl; 45 else 46 cout<<‘N‘<<endl; 47 } 48 else 49 { 50 ll h=gcd(a,b); 51 if(x%h==0&&y%h==0) 52 { 53 ll g=gcd(a-b,a+b); 54 if(abs(x+y)%g==0) 55 cout<<‘Y‘<<endl; 56 else 57 cout<<‘N‘<<endl; 58 } 59 else 60 cout<<‘N‘<<endl; 61 } 62 } 63 return 0; 64 }
以上是关于[haoi2011]向量的主要内容,如果未能解决你的问题,请参考以下文章