第八届福建省大学生程序设计竞赛 FZU 2273 Triangles (计算几何)
来源:互联网 发布:淘宝网店策划案怎么写 编辑:程序博客网 时间:2024/06/05 20:26
题目原文:http://acm.fzu.edu.cn/problem.php?pid=2273
Accept: 158 Submit: 754
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
Sample Output
题目大意:给定两个三角形六个顶点,判断两个三角形的关系(相交、相离、包含)
解题思路:
(1)通过叉积判断点与线的关系,点与这条边对应的那个顶点位于这条边的同一侧,说明这个点在这条边的内测。如果一个点位于三条边的内侧,则这个点在三角形内。如果三个顶点都在这个三角形内,说明两个三角形是包含关系。
(2)通过判断线段相交的关系,可以确定两个三角形是否存在边相交
(3)其余情况说明两个三角形相离。
AC代码:
/* @Author: wchhlbt @Date: 2017/7/17*/#include <vector>#include <list>#include <map>#include <set>#include <queue>#include <stack>#include <bitset>#include <algorithm>#include <functional>#include <numeric>#include <utility>#include <sstream>#include <iostream>#include <iomanip>#include <cstdio>#include <cmath>#include <cstdlib>#include <ctime>#include <cstring>#include <limits>#include <climits>#include <cstdio>#define Fori(x) for(int i=0;i<x;i++)#define Forj(x) for(int j=0;j<x;j++)#define maxn 10007#define inf 0x3f3f3f3f#define ONES(x) __builtin_popcount(x)#define _ << " " <<using namespace std;typedef long long ll ;const double eps =1e-8;const int mod = 1000000007;typedef pair<int, int> P;const double PI = acos(-1.0);int dx[4] = {0,0,1,-1};int dy[4] = {1,-1,0,0};typedef struct Point{ double x,y; Point(double x=0,double y=0):x(x),y(y){}}Vector;Vector operator + (const Vector & A,const Vector & B) { return Vector(A.x+B.x,A.y+B.y);}Vector operator - (const Point & A,const Point & B) { return Vector(A.x-B.x,A.y-B.y);}Vector operator * (const Vector & A,double p) { return Vector(A.x*p,A.y*p);}Vector operator / (const Vector & A,double p) { return Vector(A.x/p,A.y/p);}bool operator < (const Point &A, const Point &B){ return A.x<B.x||(A.x==B.x&&A.y<B.y);}int dcmp(double x){ if(fabs(x)<eps) return 0; return x<0? -1 : 1 ;}bool operator == (const Point &A,const Point &B){ return dcmp(A.x-B.x)==0&&dcmp(A.y-B.y)==0;}//向量点乘double Dot(const Vector &A, const Vector &B) { return A.x*B.x+A.y*B.y; }//求向量的长度或两点距离double Length(const Vector &A){ return sqrt(Dot(A,A)); }//返回两个向量夹角的弧度值double Angle(const Vector &A, const Vector &B){ return acos(Dot(A,B)/Length(A)/Length(B));}//向量叉积。共起点的两个向量A,B,若A叉乘B大于0,则B在A的左边。double Cross(const Vector &A, const Vector &B){ return A.x*B.y-A.y*B.x ;}//用叉积求三个点组成的三角形的面积。面积为0表示三点共线。double Area2(const Point &A,const Point &B,const Point &C ){return Cross(B-A,C-A) ;}//向量绕起点旋转,rad为逆时针旋转的弧度。//Rotate(A,-rad)表示将A顺时针旋转radVector Rotate(const Vector &A,double rad){ return Vector(A.x*cos(rad)-A.y*sin(rad),A.x*sin(rad)+A.y*cos(rad));}//计算A向量的单位法向量,即左转90度,将单位归一化//调用前确保A向量不是零向量Vector Normal(Vector A){ double L=Length(A); return Vector(-A.y/L,A.x/L);}//用直线的参数方程(P=P0+t*v,P0是直线上任意一点,v是直线的方向向量)求两直线的交点坐标Point GetLineIntersection(const Point & P,const Vector & v,const Point & Q,const Vector & w){ Vector u=P-Q; double t=Cross(w,u)/Cross(v,w); return P+v*t;}//点到直线的距离。平行四边形面积除以底double DistanceToLine(const Point & P,const Point & A,const Point & B){ Vector v1=B-A,v2=P-A; return fabs(Cross(v1,v2))/Length(v1);}//点到线段的距离double DistanceToSegment(const Point & P,const Point & A,const Point & B){ if(A==B) return Length(P-A); Vector v1=B-A,v2=P-A,v3=P-B; if(dcmp(Dot(v1,v2))<0) return Length(v2); else if(dcmp(Dot(v1,v3))>0) return Length(v3); else return fabs(Cross(v1,v2))/Length(v1);}//点在直线上的投影Point GetLineProjection(const Point & P,const Point & A,const Point & B){ Vector v=B-A; return A+v*(Dot(v,P-A)/Dot(v,v));}//判断点P是否在线段AB(不含端点)上bool OnSegment(const Point & P,const Point & A,const Point & B){ return dcmp(Cross(A-P,B-P))==0 && dcmp(Dot(A-P,B-P)) <0 ;}//判断两线段是否规范相交(两条线段恰有一个公共点且不在任何一个线段的端点)bool SegmentProperIntersection(const Point & a1,const Point & a2,const Point & b1,const Point & b2){ double c1=Cross(a2-a1,b1-a1) ,c2=Cross(a2-a1,b2-a1); double c3=Cross(b2-b1,a1-b1) ,c4=Cross(b2-b1,a2-b1); return dcmp(c1)*dcmp(c2)<0 && dcmp(c3)*dcmp(c4)<0 ;}//判断两线段是否规范相交(两条线段可以部分重合或者相交在某一个线段的端点)bool SegmentIntersection(const Point & a1,const Point & a2,const Point & b1,const Point & b2){ double c1=Cross(a2-a1,b1-a1) ,c2=Cross(a2-a1,b2-a1); double c3=Cross(b2-b1,a1-b1) ,c4=Cross(b2-b1,a2-b1); return dcmp(c1)*dcmp(c2)<=0 && dcmp(c3)*dcmp(c4)<=0 ;}bool SameSide(Point A, Point B, Point C, Point D)//C和D是否在AB同一侧{ Vector AB = B-A; Vector AC = C-A; Vector AD = D-A; double aaa = Cross(AB,AC); double bbb = Cross(AB,AD); if(aaa*bbb>=0) return true; // v1 and v2 should point to the same direction return false;}// Same side method// Determine whether point D in triangle ABCbool PointinTriangle1(Point A, Point B, Point C, Point D){ return SameSide(A, B, C, D) && SameSide(B, C, A, D) && SameSide(C, A, B, D) ;}int main(){ int t; cin>>t; while(t--){ int flag = 0; Point p[6]; for(int i = 0; i<6; i++) cin>>p[i].x>>p[i].y; for(int i = 0; i<3; i++){ if(SegmentIntersection(p[i],p[(i+1)%3],p[3],p[4]) || SegmentIntersection(p[i],p[(i+1)%3],p[3],p[5]) || SegmentIntersection(p[i],p[(i+1)%3],p[5],p[4])) { flag = 1; break; } } if(flag==1){ cout << "intersect" << endl; continue; } if(PointinTriangle1(p[0],p[1],p[2],p[3]) && PointinTriangle1(p[0],p[1],p[2],p[4]) && PointinTriangle1(p[0],p[1],p[2],p[5])){ cout << "contain" << endl; continue; } if(PointinTriangle1(p[3],p[4],p[5],p[0]) && PointinTriangle1(p[3],p[4],p[5],p[1]) && PointinTriangle1(p[3],p[4],p[5],p[2])){ cout << "contain" << endl; continue; } cout << "disjoint" << endl; } return 0;}
- 第八届福建省大学生程序设计竞赛 FZU 2273 Triangles (计算几何)
- 第八届福建大学生程序设计竞赛-B Triangles(简单计算几何)
- 第八届福建省大学生程序设计竞赛
- 第八届福建省大学生程序设计竞赛 重现赛 第二题 Triangles
- fzu 2278 YYS [第八届福建省大学生程序设计竞赛 Problem G] [概率]
- fzu 2275 Game [第八届福建省大学生程序设计竞赛 Problem D] [字符串匹配]
- fzu 2277 Change [第八届福建省大学生程序设计竞赛 Problem F] [线段树]
- fzu 2281 Trades [第八届福建省大学生程序设计竞赛 Problem J Trades] [贪心]
- 第八届福建省大学生程序设计竞赛 FZU 2277 Change (dfs序+树状数组)
- 2017第八届福建省大学生程序设计竞赛总结
- 第八届福建省大学生程序设计竞赛训练总结【7/12】
- 第八届福建省大学生程序设计竞赛 D.Game【思维+KMP】
- 第八届福建省大学生程序设计竞赛-重现赛 A Frog
- 第八届福建省大学生程序设计竞赛-重现赛I Magic
- 7.22.17 第八届福建省大学生程序设计竞赛-重现赛
- 第八届福建省大学生程序设计竞赛 G.YYS【期望+大数】
- FZU2272+Frog+签到题+第八届福建省大学生程序设计竞赛
- FZU2273Triangles+(三角形)+第八届福建省大学生程序设计竞赛
- 一文弄懂神经网络中的反向传播法——BackPropagation
- python str和repr的区别
- c++中static成员函数、成员变量作用
- block,inline和inline-block概念和区别
- 自定义滚轮事件
- 第八届福建省大学生程序设计竞赛 FZU 2273 Triangles (计算几何)
- spring学习之@Autowired
- Eclipse的java代码出错:The import org.apache cannot be resolved
- 排序的基本原理以及Java实现
- 慕课网学习之Java集合框架
- [LeetCode]419. Battleships in a Board
- createTrackbar函数使用
- The Suspects POJ
- 360浏览器的小功能——标题栏