题目链接:https://codeforces.com/problemset/problem/101/C
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 А:
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).
0 0
1 1
0 1
YES
0 0
1 1
1 1
YES
0 0
1 1
2 2
NO
题意:输入三个向量A,B,C。给你两个操作,1.把A向量旋转90度,2.把C向量加到A向量上,这两个操作可以执行任意多次,顺序也是任意的,问能否得到B向量;
思路;对于这种类型的题目,数据给的特别大,有1e8的数据范围,最后答案是让你判断YES和NO的情况,大多时候是需要通过一些规律或者是公式推导,最后得出一个准确的式子进行判断。
对于这道题,A向量可以在任意时间旋转90度,但如果我们对A向量进行旋转后,再把C向量连接到A向量上。这种操作需要在连接C向量后再进行旋转,对于每一次A向量旋转
都需要操作。这时我们可以将A向量的旋转转化为C向量的旋转,即对A向量连接不同个数的4种不同方向的C向量。
我们可以假设4种C向量为:C1:(x,y) C2:(-x,-y) C3:(y,-x) C4:(-y,x)
A向量为: A:(x1,y1)
B向量为: B:(x2,y2)
根据题意可以得到如下公式:
A + a * C1 + b * C2 + c * C3 + d * C4 = B
对于向量相加的知识:两个向量相加就等于向量对应分量的加和。
由此我们可以得到一个方程组:
x1 + x*(a-b) + y*(c-d) = x2
y1 + y*(a-b) - x*(c-d) = y2
令 t1=(a-b) , t2=(c-d)
得出两个方程
x1 + x * t1+ y * t2 = x2 (1)式子
y1 + y * t1 - x * t2 = y2 (2)式子
此时问题就求解二元一次方程组,判断方程组是否有整数解
需要注意:如果此时x和y都为0,只需要判断A向量能否通过四种方式的旋转得到B向量。
消元求解t1和t2的代数式:
(1)式* x+(2)式* y = x*(x1-x2) + y*(y1-y2) + t1*(xx+yy) = 0
=>t1=(x*(x1-x2) + y*(y1-y2)) / (x * x+y * y)
得出t1后判断y是否等于0,如果y=0,则代入(2)式子,t2=-((x1-x2)+x * t1) / y
否则代入(1)式子,t2=((y1-y2)+y * t1) / x
最后求出t2以后,代入原式是否相等即可。(因为要求的是整数解,所以在在一系列运算中,如果不为整数解,最后是不能出现代入原式子相等的,比如,x=4/3(下取整)=1,但x*3却不等于4)
最后上代码
#pragma GCC optimize(2)
#include<bits/stdc++.h>
using namespace std;
typedef long long ll;
const int maxn=1e6+7;
const ll mod=1e9+7;
ll m,n,i,j;
ll xx1,xx2,yy1,yy2;
ll x,y;
ll xx[10],yy[10];
ll df[10][5][5]={{{1,0},{0,1}},{{-1,0},{0,-1}},{{0,1},{-1,0}},{{0,-1},{1,0}}};
ll check(ll x2,ll y2){
ll dx=xx1-x2;
ll dy=yy1-y2;
ll sum=x*dx+y*dy;
ll t1=-sum/(x*x+y*y);
if(y!=0)
{
ll t2=-(dx+x*t1)/y;
if(xx1+x*t1+y*t2==x2&&yy1+y*t1-x*t2==y2)
return 1;
}else
{
ll t2=(dy+y*t1)/x;
if(xx1+x*t1+y*t2==x2&&yy1+y*t1-x*t2==y2)
return 1;
}
return 0;
}
int main()
{
ll flag=0;
cin>>xx1>>yy1>>xx2>>yy2>>x>>y;
for(ll i=0;i<4;i++)
{
xx[i]=df[i][0][0]*xx2+df[i][0][1]*yy2;
yy[i]=df[i][1][0]*xx2+df[i][1][1]*yy2;
}
if(x==0&&y==0)
{
for(ll i=0;i<4;i++)
if(xx1==xx[i]&&yy1==yy[i])
flag=1;
}
else
{
for(ll i=0;i<4;i++)
if(check(xx[i],yy[i])==1)
flag=1;
}
if(flag==1)
cout<<"YES";
else
cout<<"NO";
return 0;
}