题目链接:POJ 3304

Problem 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 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!

Solution

题意

给定 \(n\) 条线段,判断是否存在一条直线,使得所有线段在这条直线上的投影有公共部分。

题解

枚举 ToLeftTest

如果存在满足条件的一条直线,那么该直线的一条垂线一定与所有线段相交。

如果 \(n \le 2\) 时一定存在。

枚举所有线段的端点中任意两点构造的直线,判断是否所有线段都与之相交。

判断线段与直线相交的方法:判断线段的两个端点是否在直线的同一侧。

注意不要枚举两个相同的端点。

Code

#include <cstdio>
#include <iostream>
#include <cmath>
#include <algorithm>
#include <vector>
using namespace std;
typedef long long ll;
typedef double db;
const db eps = 1e-10;
const db pi = acos(-1.0);
const ll inf = 0x3f3f3f3f3f3f3f3f;
const ll maxn = 1e3 + 10; inline int dcmp(db x) {
if(fabs(x) < eps) return 0;
return x > 0? 1: -1;
} class Point {
public:
double x, y;
Point(double x = 0, double y = 0) : x(x), y(y) {}
void input() {
scanf("%lf%lf", &x, &y);
}
bool operator<(const Point &a) const {
return (!dcmp(x - a.x))? dcmp(y - a.y) < 0: x < a.x;
}
bool operator==(const Point &a) const {
return dcmp(x - a.x) == 0 && dcmp(y - a.y) == 0;
}
db dis2(const Point a) {
return pow(x - a.x, 2) + pow(y - a.y, 2);
}
db dis(const Point a) {
return sqrt(dis2(a));
} db dis2() {
return x * x + y * y;
}
db dis() {
return sqrt(dis2());
}
Point operator+(const Point a) {
return Point(x + a.x, y + a.y);
}
Point operator-(const Point a) {
return Point(x - a.x, y - a.y);
}
Point operator*(double p) {
return Point(x * p, y * p);
}
Point operator/(double p) {
return Point(x / p, y / p);
}
db dot(const Point a) {
return x * a.x + y * a.y;
}
db cross(const Point a) {
return x * a.y - y * a.x;
}
};
typedef Point Vector; class Line {
public:
Point s, e;
Line() {}
Line(Point s, Point e) : s(s), e(e) {}
void input() {
scanf("%lf%lf%lf%lf", &s.x, &s.y, &e.x, &e.y);
}
int toLeftTest(Point p) {
if((e - s).cross(p - s) > 0) return 1;
else if((e - s).cross(p - s) < 0) return -1;
return 0;
}
}; Line line[maxn];
Point point[maxn]; int main() {
int T;
scanf("%d", &T);
while(T--) {
int n;
scanf("%d", &n);
for(int i = 0; i < n; ++i) {
line[i].input();
point[i * 2] = line[i].s;
point[i * 2 + 1] = line[i].e;
}
if(n < 3) {
printf("Yes!\n");
continue;
}
int fg = 0;
for(int i = 0; i < 2 * n; ++i) {
for(int j = i + 1; j < 2 * n; ++j) {
if(point[i] == point[j]) continue;
Line l = Line(point[i], point[j]);
int flag = 1;
for(int k = 0; k < n; ++k) {
if(l.toLeftTest(line[k].s) + l.toLeftTest(line[k].e) && l.toLeftTest(line[k].s) == l.toLeftTest(line[k].e)) {
flag = 0;
break;
}
}
if(flag == 1) {
printf("Yes!\n");
fg = 1;
break;
}
}
if(fg == 1) {break;}
}
if(!fg) {
printf("No!\n");
}
}
return 0;
}

POJ 3304 Segments (判断直线与线段相交)的更多相关文章

  1. POJ 3304 Segments 判断直线和线段相交

    POJ 3304  Segments 题意:给定n(n<=100)条线段,问你是否存在这样的一条直线,使得所有线段投影下去后,至少都有一个交点. 思路:对于投影在所求直线上面的相交阴影,我们可以 ...

  2. POJ 3304 Segments (直线和线段相交判断)

    Segments Time Limit: 1000MS   Memory Limit: 65536K Total Submissions: 7739   Accepted: 2316 Descript ...

  3. POJ 3304 Segments (直线与线段是否相交)

    题目链接 题意 : 能否找出一条直线使得所有给定的线段在该直线上的投影有一个公共点. 思路 : 假设存在一条直线a使得所有线段在该直线上的投影有公共点,则必存在一条垂直于直线a的直线b,直线b与所有线 ...

  4. 判断直线与线段相交 POJ 3304 Segments

    题意:在二维平面中,给定一些线段,然后判断在某直线上的投影是否有公共点. 转化,既然是投影,那么就是求是否存在一条直线L和所有的线段都相交. 证明: 下面给出具体的分析:先考虑一个特殊的情况,即n=1 ...

  5. POJ 1039 Pipe(直线和线段相交判断,求交点)

    Pipe Time Limit: 1000MS   Memory Limit: 10000K Total Submissions: 8280   Accepted: 2483 Description ...

  6. poj3304(叉积判断直线和线段相交)

    题目链接:https://vjudge.net/problem/POJ-3304 题意:求是否能找到一条直线,使得n条线段在该直线的投影有公共点. 思路: 如果存在这样的直线,那么在公共投影点作直线的 ...

  7. [poj] 3304 Segments || 判断线段相交

    原题 给出n条线段,判断是否有一条直线与所有线段都有交点 若存在这样一条直线,那么一定存在一条至少过两个线段的端点的直线满足条件. 每次枚举两条线段的两个端点,确定一条直线,判断是否与其他线段都有交点 ...

  8. POJ 2074 /// 判断直线与线段相交 视野盲区

    题目大意: 将所有物体抽象成一段横向的线段 给定房子的位置和人行道的位置 接下来给定n个障碍物的位置 位置信息为(x1,x2,y) 即x1-x2的线段 y相同因为是横向的 求最长的能看到整个房子的一段 ...

  9. POJ 3304 Segments(直线)

    题目: Description Given n segments in the two dimensional space, write a program, which determines if ...

随机推荐

  1. Canal( 增量数据订阅与消费 )的理解及应用

    canal是阿里巴巴旗下的一款开源项目,纯Java开发.基于数据库增量日志解析,提供增量数据订阅&消费,目前主要支持了MySQL(也支持mariaDB). 起源:早期,阿里巴巴B2B公司因为存 ...

  2. java sigar 系统监控

    <dependency> <groupId>org</groupId> <artifactId>sigar</artifactId> < ...

  3. Excel表格文本格式的数字和数字格式如何批量转换

    Excel表格文本格式的数字和数字格式如何批量转换 在使用Excel表格对数据求和时,只能对单元格内常规格式的数据进行计算,而不能对单元格中的文本格式的数据进行计算,特点就是在单元格的左上角有一个绿色 ...

  4. VS2008中编译运行MFC应用程序时,出现无法启动程序,因为计算机中丢失mfc90ud.dll的解决方案

     解决方法:"工具"->"选项"->"项目和解决方案"->"VC++目录",在可执行文件栏中加上如 ...

  5. 自动化监控Zabbix之主机自动发现

    创建思路 首先说下自动发现强大的功能,它到底可以帮助我们完成什么工作: 快速发现并添加主机 简单的管理 随着环境的改变而快速搭建监控系统 自动发现基于网络发现功能,而网络发现又基于以下信息: IP地址 ...

  6. pyhon if分支

    在python中,最常用的就是if判断,if判断可以分为单次判断和多次判断 单次判断 if   条件 : (条件成立执行我) else:(else也可以没有,最近的else对应最近的if语句) (条件 ...

  7. [轉]Linux Data Structures

    Table of Contents, Show Frames, No Frames Chapter 15 Linux Data Structures This appendix lists the m ...

  8. 微服务-技术专区-链路追踪(pinpoint)-部署使用

    https://naver.github.io/pinpoint/ https://github.com/naver/pinpoint 背景 随着项目微服务的进行,微服务数量逐渐增加,服务间的调用也越 ...

  9. spring基于xml的事务控制

    opm配置 <?xml version="1.0" encoding="UTF-8"?> <project xmlns="http: ...

  10. 关于 群晖 docker 百度云盘下载的使用心得

    因为有了群晖,所以想折腾一下看看有什么更多的功能,今天就来折腾一下群晖百度云盘下载.毕竟现在云盘都限速了嘛... 在群晖里,要想用到百度云盘下载,就需要有个小东西,就是docker.docker很简单 ...