Problem 2273 Triangles
Accept: 201 Submit: 661
Time Limit: 1000 mSec Memory Limit : 262144
KB
Problem Description
This is a simple problem. Given two triangles A and B, you should determine they are intersect, contain or disjoint. (Public edge or point are treated as intersect.)
Input
First line contains an integer T (1 ≤ T ≤ 10), represents there are T test cases.
For each test case: X1 Y1 X2 Y2 X3 Y3 X4 Y4 X5 Y5 X6 Y6. All the coordinate are integer. (X1,Y1) , (X2,Y2), (X3,Y3) forms triangles A ; (X4,Y4) , (X5,Y5), (X6,Y6) forms triangles B.
-10000<=All the coordinate <=10000
Output
For each test case, output “intersect”, “contain” or “disjoint”.
Sample Input
2
0 0 0 1 1 0 10 10 9 9 9 10
0 0 1 1 1 0 0 0 1 1 0 1
Sample Output
disjoint
intersect
Source
第八届福建省大学生程序设计竞赛-重现赛(感谢承办方厦门理工学院)思路:先判断其中一个三角形a的顶点是否都在另一个三角形b的内部,或者有点在另一个三角形b的边上,抑或b的外部和内部都有a的顶点,这三种情况都好判断,直接输出判断结果。若a的三个顶点都在b的外部,继续判断b的三个顶点与a的关系,可能的关系:b的三个顶点都在a的外部,b的顶点在a内部外部都有,b的顶点都在a的内部。后两种情况好判断,输出结果。第一种情况则要继续判断,此时a,b的顶点都在对方三角形的外部,此时有可能相交,也有可能相离,只需要判断一下其中一个三角形的一条边是否和另一个三角形的某条边相交即可。
AC代码:
#define _CRT_SECURE_NO_DEPRECATE #include <iostream> #include<vector> #include<algorithm> #include<cstring> #include<bitset> #include<set> #include<map> #include<cmath> #include<queue> using namespace std; #define N_MAX 10000+4 #define MOD 1000000007 #define INF 0x3f3f3f3f #define EPS 1e-8 typedef long long ll; struct point { double x, y; point(double x = 0, double y = 0) :x(x), y(y) {} point operator + (point p) { return point(x + p.x, y + p.y); } point operator - (point p) { return point(x - p.x, y - p.y); } point operator * (double a) { return point(a*x, a*y); } double norm() { return x*x + y*y; } bool operator < (const point &p) const{ return x != p.x ? x + EPS < p.x : y + EPS < p.y; } }; double dot(point a,point b) { return a.x*b.x + a.y*b.y; } double det(point a,point b) { return a.x*b.y - a.y*b.x; } typedef vector<point>polygon; int contain( polygon g, point p) {//1代表在多边形内,0代表在多边形外,2在边上 int n = g.size(); bool x = 0; for (int i = 0; i < n;i++) { point a = g[i] - p, b = g[(i + 1) % n] - p; if (fabs(det(a, b)) < EPS&&dot(a, b) < EPS)return 2; if (a.y > b.y)swap(a, b); if (a.y<EPS&&b.y>EPS&&det(a, b) > EPS)x = !x; } return x ? 1 : 0; } int ccw(point a,point b,point c) {//顺时针转还是逆时针转 point x = b - a, y = c - a; if(det(x, y)>EPS)return 1; if (det(x, y) < -EPS)return -1; if (dot(a, b) < -EPS)return 2; if (a.norm() < b.norm())return -2; return 0; } int main() { int t; scanf("%d",&t); while (t--) { polygon T1, T2; T1.resize(3); T2.resize(3); for (int i = 0; i < 3; i++) scanf("%lf%lf",&T1[i].x,&T1[i].y); for (int i = 0; i < 3; i++) scanf("%lf%lf", &T2[i].x, &T2[i].y); bool is_wai = 0, is_nei = 0,flag=0; for (int i = 0; i < 3;i++) { int c = contain(T1, T2[i]); if (c==1) { is_nei = 1; } else if(c==0)is_wai = 1; else { flag = 1; break; }//在边上一定相交 } if (flag||(is_wai&&is_nei)) { puts("intersect"); continue; } if (is_nei && !is_wai) { puts("contain"); } else { is_nei = 0,is_wai=0; for (int i = 0; i < 3;i++) { int c = contain(T2,T1[i]); if (c == 1)is_nei = 1; if (c == 0)is_wai = 1; } if (is_nei&&!is_wai)puts("contain"); if (is_nei&&is_wai)puts("intersect"); else {//六个点都在另外三角形的外部,判断是否有边相交的情况 bool is_intersect = 0; point a = T1[0], b = T1[1]; for (int i = 0; i < 3; i++) { point c = T2[i], d = T2[(i + 1) % 3]; if (ccw(a, b, c)*ccw(a, b, d) <= 0 && ccw(c, d, a)*ccw(c, d, b) <= 0){ is_intersect = 1; break; } } if (is_intersect)puts("intersect"); else puts("disjoint"); } } } return 0; }