[Luogu1355]神秘大三角
题目大意:
给你一个三角形三个顶点坐标和另外一个点,问点和三角形的关系。
思路:
在顶点上时和三个顶点分别比较一下坐标即可。
在边上时算一下斜率式,判断一下是否在直线上,并且通过坐标中某个维度的值判断一下是否在线段上。
这时注意判断一下这条直线是不是竖直的,不然会被零除。
判断在三角形内外可以用面积法——就是从p往另外每两个点都连一下,判断一下面积加起来是不是等于三角形abc的面积。
1 #include<cmath> 2 #include<cstdio> 3 #include<cctype> 4 #include<algorithm> 5 inline int getint() { 6 register char ch; 7 while(!isdigit(ch=getchar())); 8 register int x=ch^'0'; 9 while(isdigit(ch=getchar())) x=(((x<<2)+x)<<1)+(ch^'0'); 10 return x; 11 } 12 struct Point { 13 int x,y; 14 bool operator == (const Point &another) const { 15 return x==another.x&&y==another.y; 16 } 17 }; 18 inline double sqr(const int &x) { 19 return x*x; 20 } 21 inline double dis(const Point &a,const Point &b) { 22 return sqrt(sqr(a.x-b.x)+sqr(a.y-b.y)); 23 } 24 inline double sum(const Point &x,const Point &y,const Point &z) { 25 const double a=dis(y,z),b=dis(x,z),c=dis(x,y),p=(a+b+c)/2; 26 return sqrt(p*(p-a)*(p-b)*(p-c)); 27 } 28 int main() { 29 Point a=(Point){getint(),getint()},b=(Point){getint(),getint()},c=(Point){getint(),getint()},p=(Point){getint(),getint()}; 30 if(p==a||p==b||p==c) { 31 puts("4"); 32 return 0; 33 } 34 if(a.x>b.x) std::swap(a,b); 35 if(p.x>=a.x&&p.x<=b.x) { 36 if(a.x==b.x) { 37 if(a.y>b.y) std::swap(a,b); 38 if(a.y<=p.y&&p.y<=b.y) { 39 puts("3"); 40 return 0; 41 } 42 } else if((b.y-a.y)/(b.x-a.x)*(p.x-a.x)+a.y==p.y) { 43 puts("3"); 44 return 0; 45 } 46 } 47 if(a.x>c.x) std::swap(a,c); 48 if(p.x>=a.x&&p.x<=c.x) { 49 if(a.x==c.x) { 50 if(a.y>c.y) std::swap(a,c); 51 if(a.y<=p.y&&p.y<=c.y) { 52 puts("3"); 53 return 0; 54 } 55 } else if((c.y-a.y)/(c.x-a.x)*(p.x-a.x)+a.y==p.y) { 56 puts("3"); 57 return 0; 58 } 59 } 60 if(b.x>c.x) std::swap(b,c); 61 if(p.x>=b.x&&p.x<=c.x) { 62 if(b.x==c.x) { 63 if(b.y>c.y) std::swap(b,c); 64 if(b.y<=p.y&&p.y<=c.y) { 65 puts("3"); 66 return 0; 67 } 68 } else if((c.y-b.y)/(c.x-b.x)*(p.x-b.x)+b.y==p.y) { 69 puts("3"); 70 return 0; 71 } 72 } 73 if(abs(sum(a,b,p)+sum(a,c,p)+sum(b,c,p)-sum(a,b,c))<1e-5) { 74 puts("1"); 75 } else { 76 puts("2"); 77 } 78 return 0; 79 }