POJ 3304 - Segments【计算几何 - 直线线段相交判断】
来源:互联网 发布:2016淘宝有前景的类目 编辑:程序博客网 时间:2024/04/30 19:41
Segments
Time Limit: 1000MSMemory Limit: 65536KB
Description:
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 x1y1x2y2 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!
题意:
给你n条线段的两端点坐标,求是否存在一条直线,使所有线段到这条直线的投影至少有一个交点。
算法分析:
若存在一条直线l和所有线段相交,过投影相交区域作直线的垂线,该垂线必定与每条线段相交,问题转化为问是否存在一条线和所有线段相交直线肯定经过两个端点。从而将题目简化成枚举端点,判断直线和线段是否相交的问题!
代码实现:
#include <iostream>#include <stdio.h>#include <string.h>#include <algorithm>#include <math.h>#include <map>#include <queue>#include <vector>#include <stack>using namespace std;const double eps = 1e-8;const int Max = 105;int n;struct Point{ double x, y; Point(double x = 0, double y = 0) : x(x), y(y){ }}s[Max], e[Max];typedef Point Vector;Vector operator - (Vector A, Vector B) { return Vector(A.x - B.x, A.y - B.y); }double Cross(Vector A, Vector B)///叉积计算{ return A.x * B.y - A.y * B.x;}double Area2(Point A, Point B, Point C){ return Cross(A - C, B - C);}bool solve(Point a, Point b){ if(fabs(a.x - b.x) < eps && fabs(a.y - b.y) < eps) return false; for(int i = 0; i < n; i++) if(Area2(a,b,s[i]) * Area2(a,b,e[i]) > eps)///叉积判断两个点是否在同一侧,在返回false,不再返回false return false; return true;}int main(){ int t; scanf("%d",&t); while(t--) { scanf("%d",&n); for(int i = 0; i < n; i++) scanf("%lf %lf %lf %lf",&s[i].x,&s[i].y,&e[i].x,&e[i].y); int ans = 0; if(n < 3) ans = 1; for(int i = 0; i < n && !ans; i++)///枚举线段端点判断是否存在直线 for(int j = i + 1; j < n && !ans; j++) { if(solve(s[i],s[j])) ans = 1; else if(solve(s[i],e[j])) ans = 1; else if(solve(e[i],s[j])) ans = 1; else if(solve(e[i],e[j])) ans = 1; } if(ans) printf("Yes!\n"); else printf("No!\n"); } return 0;}
0 0
- POJ 3304 - Segments【计算几何 - 直线线段相交判断】
- POJ 3304 Segments(计算几何:直线与线段相交)
- POJ 3304 Segments(计算几何 判断直线与线段相交)
- POJ 3304 Segments (计算几何、判断直线与线段是否相交)
- POJ 3304 Segments <计算几何(直线与线段相交判断)>
- POJ 3304:Segments 计算几何 是否有直线与所有线段相交
- poj 3304 Segments(判断直线与线段相交)
- POJ 3304 Segments (判断直线和线段是否相交)
- poj 3304 Segments(判断线段和直线相交)
- POJ 3304 Segments [判断线段和直线相交]
- POJ 3304 Segments 判断直线与线段相交
- POJ 3304 Segments(判断线段和直线是否相交)
- POJ 3304 Segments(判断直线和线段相交)
- POJ 3304 Segments (直线和线段相交判断)
- POJ 3304 Segments (直线和线段相交判断)
- poj 3304 Segments(叉积+直线和线段相交判断)
- POJ 3304 Segments [枚举+叉乘判断线段相交]【计算几何】
- POJ 3304 Segments 【计算几何】【直线和线段的关系】
- 黑马程序员07 IO流
- 快学Scala习题解答—第十一章 操作符
- tiny_mce
- 散列技术之线性探测法
- php---魔术方法(__wakeup和__sleep)
- POJ 3304 - Segments【计算几何 - 直线线段相交判断】
- 文章标题
- 从上往下打印二叉树
- docker/compose项目笔记
- 卷积的物理意义
- C#实现磁性窗体(吸附、剥离、移动)
- Beginning Auto Layout Tutorial in iOS 7: Part 2
- UI -视图控制器UIViewController
- 支付宝简单使用