洛谷 P1355 神秘大三角(计算几何基础)

P1355 神秘大三角
题目提供者yeszy
标签 福建省历届夏令营
难度 普及/提高-
题目描述
判断一个点与已知三角形的位置关系。
输入输出格式
输入格式:
前三行:每行一个坐标,表示该三角形的三个顶点
第四行:一个点的坐标,试判断该点与前三个点围成三角形的位置关系
(详见样例)
所有坐标值均为整数。
输出格式:
若点在三角形内(不含边界),输出1;
若点在三角形外(不含边界),输出2;
若点在三角形边界上(不含顶点),输出3;
若点在三角形顶点上,输出4。
输入输出样例
输入样例#1:
(0,0)
(3,0)
(0,3)
(1,1)
输出样例#1:
1
说明
【数据规模与约定】
对于100%数据,0<=所有点的横、纵坐标<=100

/*
计算几何第一题留念flag.
判断三角形的位置.
用点积和叉积.
所谓点积就是我们平常说得数量积,结果是一个数量.
A·B=|A||B|cos<A,B>=x1*x2+y1*y2.
而叉积的结果是一个向量,是垂直于向量a,b所形成的平面
A×B=|A||B|sin<A,B>=x1*y2-x2*y1. 
在顶点上的直接判就可以了.
在边上的话有PA×PB=0&&PA·PB<0充要条件.
在内部我们可以得到互不相同的两个叉积(P点为始点)和的模 
等于三角形任意两边叉积的模.
否则就在外边咯.
*/
#include<iostream>
#include<cstdio>
#define MAXN 1001
using namespace std;
int x1,y1,x2,y2,x3,y3,x,y;
bool flag;
inline int read()
{
    int x=0,f=1;char ch=getchar();
    while(ch<'0'||ch>'9'){if(ch=='-')f=-1;ch=getchar();}
    while(ch>='0'&&ch<='9') x=x*10+ch-48,ch=getchar();
    return x*f;
}
int fabs(int x)
{
    return x<0?-x:x;
}
void slove()
{
    if(x1==x&&y1==y) flag=true,printf("4");
    else if(x2==x&&y2==y) flag=true,printf("4");
    else if(x3==x&&y3==y) flag=true,printf("4");
}
void slove2()
{
    int a,b;
    a=(x1-x)*(y2-y)-(y1-y)*(x2-x);
    b=(x1-x)*(x2-x)+(y1-y)*(y2-y);
    if(!a&&b<0) flag=true,printf("3");
    a=(x1-x)*(y3-y)-(x3-x)*(y1-y);
    b=(x1-x)*(x3-x)+(y1-y)*(y3-y);
    if(!a&&b<0) flag=true,printf("3");
    a=(x3-x)*(y2-y)-(y3-y)*(x2-x);
    b=(x3-x)*(x2-x)+(y3-y)*(y2-y);
    if(!a&&b<0) flag=true,printf("3");
}
void slove3()
{
    int a,b,c,A;
    a=fabs((x1-x)*(y2-y)-(y1-y)*(x2-x));//PA*PB.
    b=fabs((x1-x)*(y3-y)-(y1-y)*(x3-x));//PA*PC.
    c=fabs((x3-x)*(y2-y)-(y3-y)*(x2-x));//PB*PC.
    A=fabs((x1-x2)*(y1-y3)-(y1-y2)*(x1-x3));//AB*AC.
    if(a+b+c==A) flag=true,printf("1");
}
int main()
{
    x1=read(),y1=read(),x2=read(),y2=read(),x3=read(),y3=read();
    x=read(),y=read();
    slove();
    if(!flag) slove2();
    if(!flag) slove3();
    if(!flag) printf("2");
    return 0;
}
原文地址:https://www.cnblogs.com/nancheng58/p/10068134.html