题目描述
判断一个点与已知三角形的位置关系。
输入输出格式
输入格式:
前三行:每行一个坐标,表示该三角形的三个顶点
第四行:一个点的坐标,试判断该点与前三个点围成三角形的位置关系
(详见样例)
所有坐标值均为整数。
输出格式:
若点在三角形内(不含边界),输出1;
若点在三角形外(不含边界),输出2;
若点在三角形边界上(不含顶点),输出3;
若点在三角形顶点上,输出4。
输入输出样例
说明
【数据规模与约定】
对于100%数据,0<=所有点的横、纵坐标<=100
思路:
1、因为若点在三角形外,将构成四个三角形,总的面积必定大于原三角形(可自己画图证明,非常明了,图是个好东西【表达对spfa和深广搜与数的怀念】)
2、若点在三角形内,则构成的三角型面积为原三角形(不懂画图)。若有点在边上或点上,就一定会有一个三角形面积为0。在点上就直接判断是否重复,然后就over了。
(要用到海伦公式,当然也可以用叉积)
叉积代码(一同学的,pascal,请自行翻译):
var
x,y:array[1..4]of longint;
i,j,k,ans:longint;
t,w,p,s:double;
z:string;
function try(a,b,c:longint):double;
begin
try:=abs((x[b]-x[a])*(y[c]-y[a])-(x[c]-x[a])*(y[b]-y[a]))/2;
end;
begin
for i:=1 to 4 do
begin
readln(z);
delete(z,1,1);
k:=pos(',',z);
val(copy(z,1,k-1),x[i]);
delete(z,1,k);
k:=pos(')',z);
val(copy(z,1,k-1),y[i]);
end;
t:=try(1,2,3);
w:=try(1,2,4);
p:=try(1,3,4);
s:=try(2,3,4);
if w=0 then inc(ans);
if p=0 then inc(ans);
if s=0 then inc(ans);
if w+p+s>t then write(2)
else if ans=0 then write(1)
else if ans=1 then write(3)
else write(4);
end.
海伦代码:
// luogu-judger-enable-o2
// luogu-judger-enable-o2
#include<iostream>
#include<cstdio>
#include<string>
#include<cmath>
#include<memory.h>
using namespace std;
int x[5],y[5],z[5];
char c;
double Heron(int a,int b,int x,int y,int n,int m)
{
double p,ab,ac,bc;
ab=sqrt((a-x)*(a-x)+(b-y)*(b-y));
ac=sqrt((a-n)*(a-n)+(b-m)*(b-m));
bc=sqrt((x-n)*(x-n)+(y-m)*(y-m));
p=(ab+ac+bc)/2;
return sqrt(p*(p-ab)*(p-ac)*(p-bc));
}
int main()
{
for(int i=1;i<=4;i++)
cin>>c>>x[i]>>c>>y[i]>>c;
for(int i=1;i<=3;i++)
if(x[i]==x[4]&&y[i]==y[4])
{
printf("4\n");
return 0;
}
z[1]=(int)Heron(x[1],y[1],x[2],y[2],x[3],y[3])*100;
z[2]=(int)Heron(x[1],y[1],x[3],y[3],x[4],y[4])*100;
z[3]=(int)Heron(x[1],y[1],x[2],y[2],x[4],y[4])*100;
z[4]=(int)Heron(x[2],y[2],x[3],y[3],x[4],y[4])*100;
if(z[4]+z[2]+z[3]>z[1])
{
printf("2\n");
return 0;
}
else
{
if(z[4]==0 || z[2]==0 || z[3]==0)
{
printf("3\n");
return 0;
}
printf("1\n");
}
return 0;
}