题目来源:NEFU OJ-760 向右转
题目描述
相信同学们都经过军训,每当听到严厉的教官喊“向右转,齐步走!”,相信你没有胆量向左转吧!现在的问题是这样的:给定三个点A,B,C,
教官要求你踏着正步,从A点经过B点到达C点,问该同学在B点是向右转还是向左转还是沿着直线走?
输入描述
输入数据有T(T <= 100)组,每组1行,即依次是A,B,C的坐标,A,B,C的坐标值均为整数,且没有两点的坐标是重合的,数据范围均在int内。
输出描述
在B点如果向右转输出“Right”,向左转输出“Left”,沿着直线走则输出“Straight”
输入样例
3
0 0 0 1 1 1
0 0 0 1 -1 1
0 0 0 1 0 4
输出样例
Right
Left
Straight
OP
下面有两种解法,一种是通过向量叉乘的(不了解向量叉乘的可以戳这里,里面图示非常直观),另一种是通过解析几何方法,不过比较麻烦。
叉乘
思路
性质,方向遵循右手定则,具体戳上面的链接即可。
代码
#include<bits/stdc++.h>
using namespace std;
typedef long long ll;
const ll M=10007;
int main()
{
int xa,ya,xb,yb,xc,yc,k,b,del;
cin>>xa;//原题中t可以不要
while(cin>>xa>>ya>>xb>>yb>>xc>>yc)
{
int x1,y1,x2,y2;//两向量的坐标表示
x1=xb-xa;
y1=yb-ya;
x2=xc-xb;
y2=yc-yb;
del=x1*y2-y1*x2;//计算叉乘
if(del==0)printf("Straight\n");
else if(del>0)printf("Left\n");
else printf("Right\n");
}
return 0;
}
解析几何
思路
这个思路是没了解叉乘之前做的,略麻烦,但是也能A。
首先进行判直,这个通过计算斜率的式子变形即可避免除0问题。
接下来进行左右判定:
在高中数学的点到直线距离公式中,分子被绝对值套住的一部分表面是防止距离变负,实际上也可以作为判定点与该直线上下关系(y轴方向)的判据(该值为正,点在直线之上;反之在之下;为0即点在线上);
这道题中左右判定除了点与线的上下关系,还需要A点与B点的左右关系;
仅说结论即为:(A在B左 && 点在线上)||(A在B右 && 点在线下)为左转;反之为右转。
具体实现上,我选择用点斜式直接变形为一般式,对于斜率不存在的情况,我们可以添加一个微小的误差,使斜率存在。
代码
#include<bits/stdc++.h>
using namespace std;
typedef long long ll;
const ll M=10007;
int main()
{
double xa,ya,xb,yb,xc,yc,k,b,del;
cin>>xa;
while(cin>>xa>>ya>>xb>>yb>>xc>>yc)
{
if(fabs((ya-yb)*(xc-xb)-(yc-yb)*(xa-xb))<=0.0001)//判直
{
printf("Straight\n");
continue;
}
if(fabs(xa-xb)<=0.0001)xb+=0.0001;//添加误差
k=(ya-yb)/(xa-xb);
b=ya-k*xa;//求直线系数
del=xb-xa;//AB相对位置
if((-k*xc+yc-b)*(del)>0)printf("Left\n");//判
else printf("Right\n");
}
return 0;
}
ED
叉乘真好用!!