判断直线与线段相交 POJ 3304 Segments
题意:在二维平面中,给定一些线段,然后判断在某直线上的投影是否有公共点。
转化,既然是投影,那么就是求是否存在一条直线L和所有的线段都相交。
证明:
下面给出具体的分析:先考虑一个特殊的情况,即n=1的时候,如下图,线段AB在直线L上的投影为线段A'B',则过任意介于A'B'之间的点C'做直线L的垂线必交线段AB与一点C;反之,过线段AB之间任意一点C做直线L的垂线,垂足必定落在A'B'之间。
不难将此结论推广到n条线段的情况,假设存在一满足题意的直线L,则设点A为各个线段在L上投影的公共点,那么过A做一条直线L的垂线L',则L'必定与n条线段都相交;反之,过所有线段做一个直线L1使其与n条线段均相交,做直线L1的垂线L2,容易发现垂足即为所有n条线段投影的公共点。
---------摘自http://blog.csdn.net/Once_HNU/article/details/6327906
判断直线和线段相交,这个和判断线段和线段相交差不多,从直线上任取两个点,和线段的端点比较,如果两个在同一侧,那么就不相交,反之,就相交。关键问题就是怎么找这个直线, 假设存在一条直线跟所有线段都相交,我们可以让这个直线旋转,条件是旋转之后仍然相交,所有一定有个临界条件,而且这个临界条件一定发生在线段的端点处, 所以,可以通过枚举所有 线段端点的方式来求这个直线。
还有需要注意的是:
1. n = 1, n = 2时要特判,因为2条线段一定可以找第三条直线与他们相交
2. 如果枚举线段端点的时候,两个点的距离小于10^-8,那么就跳过此直线。由于计算机在浮点类型的计算中1e-8会当成三点共线来算,所以不能用它来当成要求的那条直线。
代码如下:
/*************************************************************************
> File Name: poj_3304.cpp
> Author:
> Mail:
> Created Time: 2015年04月01日 星期三 19时01分05秒
************************************************************************/ #include<iostream>
#include <cstdio>
#include <math.h>
#define EPS 1e-8
using namespace std;
struct point{
double x, y;
};
const int N = ;
point p[N];
int T, n;
//直线的叉积,来判断点在直线ab的哪一侧
double get_direction(point a, point b, point c)
{
point t1, t2;
t1.x = c.x - a.x; t1.y = c.y - a.y;
t2.x = b.x - a.x; t2.y = b.y - a.y;
return (t1.x * t2.y - t1.y * t2.x);
}
//算两点之间的距离
double get_distance(int i, int j)
{
return sqrt((p[j].x - p[i].x) * (p[j].x - p[i].x) + (p[j].y - p[i].y) * (p[j].y - p[i].y));
}
int main()
{
scanf("%d", &T);
while (T--)
{
double d1, d2;
bool flag = false;
scanf("%d", &n);
for (int i = ; i < * n; i++)
scanf("%lf %lf", &p[i].x, &p[i].y);
if (n == || n == )//特判
{
puts("Yes!");
continue;
}
for (int i = ; i < * n; i++)
{
for (int j = i + ; j < * n; j++)//这两层for是枚举所有的线段端点所在直线
{
if (get_distance(i, j) < EPS)//精度
continue;
bool tmp_flag = true;
for (int k = ; k < * n; k++)
{
d1 = get_direction(p[i], p[j], p[k]);
d2 = get_direction(p[i], p[j], p[++k]);
if (d1 * d2 > )
{
tmp_flag = false;
break;
}
}
if (tmp_flag)//如果找到直接跳出循环
{
flag = true;
break;
}
}
if (flag)//优化,找到之后直接跳出循环
break;
}
if (flag)
puts("Yes!");
else
puts("No!");
} return ;
}
判断直线与线段相交 POJ 3304 Segments的更多相关文章
- POJ 3304 Segments 判断直线和线段相交
POJ 3304 Segments 题意:给定n(n<=100)条线段,问你是否存在这样的一条直线,使得所有线段投影下去后,至少都有一个交点. 思路:对于投影在所求直线上面的相交阴影,我们可以 ...
- POJ 3304 Segments (判断直线与线段相交)
题目链接:POJ 3304 Problem Description Given n segments in the two dimensional space, write a program, wh ...
- 简单几何(直线与线段相交) POJ 1039 Pipe
题目传送门 题意:一根管道,有光源从入口发射,问光源最远到达的地方. 分析:黑书上的例题,解法是枚举任意的一个上顶点和一个下顶点(优化后),组成直线,如果直线与所有竖直线段有交点,则表示能穿过管道. ...
- poj3304(叉积判断直线和线段相交)
题目链接:https://vjudge.net/problem/POJ-3304 题意:求是否能找到一条直线,使得n条线段在该直线的投影有公共点. 思路: 如果存在这样的直线,那么在公共投影点作直线的 ...
- POJ 2074 /// 判断直线与线段相交 视野盲区
题目大意: 将所有物体抽象成一段横向的线段 给定房子的位置和人行道的位置 接下来给定n个障碍物的位置 位置信息为(x1,x2,y) 即x1-x2的线段 y相同因为是横向的 求最长的能看到整个房子的一段 ...
- poj 3304(直线与线段相交)
传送门:Segments 题意:线段在一个直线上的摄影相交 求求是否存在一条直线,使所有线段到这条直线的投影至少有一个交点 分析:可以在共同投影处作原直线的垂线,则该垂线与所有线段都相交<==& ...
- POJ 1039 Pipe(直线和线段相交判断,求交点)
Pipe Time Limit: 1000MS Memory Limit: 10000K Total Submissions: 8280 Accepted: 2483 Description ...
- hdu 3304(直线与线段相交)
Segments Time Limit: 1000MS Memory Limit: 65536K Total Submissions: 12042 Accepted: 3808 Descrip ...
- POJ 1039 直线和线段相交
题意: 题意很好理解,从左边射过来的光线,最远能经过管道到右边多少距离. 分析: 光线一定经过一个上端点和一个下端点,这一点很容易想到.然后枚举上下端点即可 #include <iostream ...
随机推荐
- 不熟悉的CSS样式
1.font连写: 例如:font:15px/23px "ralewayregular","Helvetica Neue",Helvetica,Arial,sa ...
- Linux命令学习计划【sed】
引言: Sed命令是linux里用于文本行处理的命令. 为了便于说明,我在/usr/dict下创建了字典words并以此作为演示模板 先用nl 打印下words内容: *打印篇: Q1:如何打印某一行 ...
- date命令详解与练习
date : 用来打印或设置系统日期和时间. 它在linux shell编程中经常会用到.比如每天生成随日期变化的档案名,尤其在银行业务中每天都会生成流水文件.eg:datefile=$(date & ...
- (转载)图解Linux系统的系统架构
我以下图为基础,说明Linux的架构(architecture).(该图参考<Advanced Programming in Unix Environment>) 最内层是硬件,最外层是用 ...
- Fedora21源配置与显卡安装
1. 安装fastestmirror Fedora的源速度很慢,令人很烦恼,不过它有个自动选最快的源包. yum install yum-fastestmirror yum-presto 它会判断你的 ...
- 9 Palindrome Number(判断是否为回文数Easy)
题目意思:判断是否为回文数,不许使用额外空间 ps:一直不理解额外空间的意思,int能用吗 思路:1.比较头尾 2.翻转,越界问题需考虑 class Solution { public: bool i ...
- [jQuery编程挑战]002:实现一个转盘大抽奖
body { background-color: #F2F2F2; text-align: center; } .container { position: relative; width: 500p ...
- php 带cookie登陆
<?php /** * @version $id */ define('SCRIPT_ROOT',dirname(__FILE__).'/'); $act = trim($_REQUEST['a ...
- SCJP_104——题目分析(1)
1.1) public class ReturnIt{2) returnType methodA(byte x, double y){3) return (short)x/y*2;4) }5) }wh ...
- DropzoneJS 可以拖拽上传的js库
介绍 可以拖拽上传的 js库 网址 http://www.dropzonejs.com/ 同类类库 1.jquery.fileupload http://blueimp.github.io/jQu ...
