poj 3304 Segments
2016-05-05 16:14
190 查看
Segments
Given n segments in the two dimensional space, write a program, which determines if there exists a line such that after projecting these segments on it, all projected segments have at least one point in common. Input Input begins with a number T showing the number of test cases and then, T test cases follow. Each test case begins with a line containing a positive integer n ≤ 100 showing the number of segments. After that, n lines containing four real numbers x1 y1 x2 y2 follow, in which (x1, y1) and (x2, y2) are the coordinates of the two endpoints for one of the segments. Output For each test case, your program must output "Yes!", if a line with desired property exists and must output "No!" otherwise. You must assume that two floating point numbers a and b are equal if |a - b| < 10-8. Sample Input 3 2 1.0 2.0 3.0 4.0 4.0 5.0 6.0 7.0 3 0.0 0.0 0.0 1.0 0.0 1.0 0.0 2.0 1.0 1.0 2.0 1.0 3 0.0 0.0 0.0 1.0 0.0 2.0 0.0 3.0 1.0 1.0 2.0 1.0 Sample Output Yes! Yes! No! Source Amirkabir University of Technology Local Contest 2006 |
[Discuss]
题意:
给定一些线段,判断存在不存在一条直线2,使任意两条线段在直线2的投影都有公共点思路:
假如存在一条直线1,可以穿过所有的线段,那么做这条直线1的垂线就是所求直线2(枚举任意两线段的端点,看其他线段的点是否都在这条直线两侧,叉积来做)代码:
#include <set> #include <map> #include <list> #include <cmath> #include <ctime> #include <deque> #include <queue> #include <stack> #include <cctype> #include <cstdio> #include <string> #include <vector> #include <cassert> #include <cstdlib> #include <cstring> #include <sstream> #include <iostream> #include <algorithm> #define pi acos(-1.0) #define maxn (100 + 50) #define mod 1000000007 #define Lowbit(x) (x & (-x)) using namespace std; typedef long long int LLI; struct Point { double x; double y; Point() {} Point(double xx,double yy) { x = xx,y = yy; } Point operator-(const Point &b)const { return Point(x - b.x,y - b.y); } double operator*(const Point &b)const { return x * b.x + y * b.y; } double operator^(const Point &b)const { return x * b.y - y * b.x; } }; struct Line { Point Start; Point End; Line() {} Line(Point s,Point e) { Start = s; End = e; } } line[maxn * 2]; double Xmult(Point p0,Point p1,Point p2) { return (p1 - p0) ^ (p2 - p0); } bool Judge(Point a,Point b,int n) { if(abs(a.x - b.x) < 1e-8 && abs(a.y - b.y) < 1e-8) return false; for(int i = 1; i <= n; i ++) { if(Xmult(line[i].Start,a,b) * Xmult(line[i].End,a,b) > 1e-8) return false; } return true; } bool Fun(int n) { for(int i = 1; i <= n; i ++) { for(int j = i + 1; j <= n; j ++) { if(Judge(line[i].Start,line[j].End,n)) return true; if(Judge(line[i].End,line[j].End,n)) return true; if(Judge(line[i].Start,line[j].Start,n)) return true; if(Judge(line[i].End,line[j].Start,n)) return true; } } return false; } int main() { // freopen("in.txt", "r", stdin); // freopen("out.txt", "w", stdout); int t; scanf("%d",&t); while(t --) { int n; scanf("%d",&n); for(int i = 1; i <= n; i ++) { double x1,x2,y1,y2; scanf("%lf%lf%lf%lf",&x1,&y1,&x2,&y2); line[i] = Line(Point(x1,y1),Point(x2,y2)); } if(n == 1 || Fun(n) == true) printf("Yes!\n");(n == 1 时,不能进入循环,需特判) else printf("No!\n"); } return 0; }
相关文章推荐
- 初学算法 - 求凸包的Garham's Scan算法的C++实现
- 【Google Code Jam 2009 round2 problem D】Watering Plants (两圆交点求法详解)
- 计算几何模板
- 计算几何小模板
- BZOJ2829信用卡凸包
- HDU 4922 Hello, Your Package! (计算几何+DP)(WA)
- poj 1514&zoj 1185 Metal Cutting(半平面交)
- UVA 10969 Sweet Dream(圆的相交)
- uva 11177 Fighting Against a Polygonal Monster(凸包与圆的面积交)
- POJ1279 && LA2512 Art Gallery(求多边形的核)
- poj 2540 && uva 10084 Hotter Colder(半平面交)
- UVALive 5878 - Shortest Leash 【计算几何】
- 【计算几何】POJ 2318 & POJ 2398
- 【计算几何】POJ 2653
- 【计算几何】POJ 1113
- HDU 5128 The E-pang Palace
- POJ 2318 TOYS(叉积+二分or暴力)
- POJ 2398 Toy Storage(叉积+二分)
- POJ 1228 Grandpa's Estate 计算凸包+判断点在线段上
- POJ 1873 The Fortified Forest 计算凸包