http://poj.org/problem?id=3304

Segments
Time Limit: 1000MS   Memory Limit: 65536K
Total Submissions: 9449   Accepted: 2902

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 (x1y1) and (x2y2) 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!

$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$

简短的题目描述,但题目确实挺难的

别人的题解很详细,我就不献丑了,下面题解的连接:http://hi.baidu.com/cloudayc/item/243f3c4c2a687aaadf2a9fb7

证明:坐标系内若干线段,是否存在一条直线与每条线段都有交点

转成叉积计算线段和直线是否相交,注意重点

转自discuss上的证明:from hanjialong

首先题中的要求等价于:存在一条直线l和所有的线段都相交。
证明:若存在一条直线l和所有线段相交,作一条直线m和l垂直,则m就是题中要求的直线,所有线段投影的一个公共点即为垂足。(l和每条线段的交点沿l投影到m上的垂足处)
反过来,若存在m,所有线段在m上的投影有公共点,则过这点垂直于m作直线l,l一定和所有线段相交。

然后证存在l和所有线段相交等价于存在l过某两条线段的各一个端点且和所有线段相交。
充分性显然。必要性:若有l和所有线段相交,则可保持l和所有线段相交,左右平移l到和某一线段交于端点停止(“移不动了”)。然后绕这个交点旋转。也是转到“转不动了”(和另一线段交于其一个端点)为止。这样就找到了一个新的l。

于是本题可归结为枚举两两线段的各一个端点,连一条直线,再判断剩下的线段是否都和这条直线有交点。

 #include <stdio.h>
#include <string.h>
#include <stdlib.h>
#include <iostream>
#include <algorithm>
#include <math.h> using namespace std;
#define eps 1e-8
#define MAXX 1010 typedef struct point
{
double x;
double y;
}point; typedef struct line
{
point st;
point ed;
}line; point p[MAXX];
line li[MAXX]; bool dy(double x,double y){ return x>y+eps; }
bool xy(double x,double y){ return x<y-eps; }
bool dyd(double x,double y){ return x>y-eps; }
bool xyd(double x,double y){ return x<y+eps; }
bool dd(double x,double y){ return fabs(x-y)<eps; } double crossProduct(point a,point b,point c)
{
return (c.x-a.x)*(b.y-a.y)-(c.y-a.y)*(b.x-a.x);
} double dist(point a,point b)
{
return sqrt((b.x-a.x)*(b.x-a.x)+(b.y-a.y)*(b.y-a.y));
} bool onSegment(point a,point b,point c)
{
double maxx=max(a.x,b.x);
double maxy=max(a.y,b.y);
double minx=min(a.x,b.x);
double miny=min(a.y,b.y);
if(dd(crossProduct(a,b,c),0.0) && xyd(c.x,maxx) && dyd(c.x,minx) && xyd(c.y,maxy) && dyd(c.y,miny))
return true;
return false;
} bool segIntersect(point p1,point p2,point p3,point p4)
{
double d1=crossProduct(p3,p4,p1);
double d2=crossProduct(p3,p4,p2);
double d3=crossProduct(p1,p2,p3);
double d4=crossProduct(p1,p2,p4);
/*if(xy(d1*d2,0.0) && xy(d3*d4,0.0))
return true;
if(dd(d1,0.0) && onSegment(p3,p4,p1))
return true;
if(dd(d2,0.0) && onSegment(p3,p4,p2))
return true;
if(dd(d3,0.0) && onSegment(p1,p2,p3))
return true;
if(dd(d4,0.0) && onSegment(p1,p2,p4))
return true;
return false;*/
return xyd(d1 * d2,0.0);
} int main()
{
int n,m,i,j,t;
//freopen("in.txt","r",stdin);
scanf("%d",&t);
while(t--)
{
scanf("%d",&n);
int sub=,suc=;
for(i=; i<n; i++)
{
scanf("%lf%lf%lf%lf",&p[sub].x,&p[sub].y,&p[sub+].x,&p[sub+].y);
sub += ;
li[suc].st.x=p[sub-].x;
li[suc].st.y=p[sub-].y;
li[suc].ed.x=p[sub-].x;
li[suc++].ed.y=p[sub-].y;
}
if(n == || n == )
{
printf("Yes!\n");
continue;
}
bool flag=false;
for(i=; i<sub; i++)
{
for(j=i+; j<sub; j++)
{
int sum=;
if(dist(p[i],p[j]) < eps)
continue;
for(int k=; k<suc; k++)
{
if(!segIntersect(li[k].st,li[k].ed,p[i],p[j]))
{
break;
}
else
sum++;
}//printf("%d***",sum);//test
if(sum >= n)
{
flag=true;
goto end;
}
//else sum=0;
}
}
end:;
if(flag)printf("Yes!\n");
else printf("No!\n");
}
return ;
}

poj 3304线段与直线相交的更多相关文章

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

    // 判断线段和直线相交 POJ 3304 // 思路: // 如果存在一条直线和所有线段相交,那么平移该直线一定可以经过线段上任意两个点,并且和所有线段相交. #include <cstdio ...

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

    题目链接:POJ 3304 Problem Description Given n segments in the two dimensional space, write a program, wh ...

  3. POJ 1039 Pipe【经典线段与直线相交】

    链接: http://poj.org/problem?id=1039 http://acm.hust.edu.cn/vjudge/contest/view.action?cid=22013#probl ...

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

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

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

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

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

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

  7. poj 3304 Segments 线段与直线相交

    Segments Time Limit: 1000MS   Memory Limit: 65536K       Description Given n segments in the two dim ...

  8. poj 1269 Intersecting Lines(直线相交)

    Intersecting Lines Time Limit: 1000MS   Memory Limit: 10000K Total Submissions: 8637   Accepted: 391 ...

  9. POJ 3304 segments 线段和直线相交

    Segments Time Limit: 1000MS   Memory Limit: 65536K Total Submissions: 14178   Accepted: 4521 Descrip ...

随机推荐

  1. JNI 回调小记

    javah在eclipse中设置参数:location(javah.exe的位置)working dir(${project_loc}/src) -classpath .;./classes -d $ ...

  2. View Properties [AX 2012]

    View Properties [AX 2012] Other Versions This topic has not yet been rated - Rate this topic Updated ...

  3. org.hibernate.TransientObjectException

    使用JPA注解@ManyToMany做一个多对多的用例. 为了避免在删除主表数据时同时级联删除从表数据,JPA官方文档建议在主表的从表字段使用级联注解:CascadeType.PERSIST,Casc ...

  4. Oracle 临时表

    一.临时表的介绍: Oracle的临时表只存在于某个会话或者事物的生命周期里,此时临时表中的数据只对当前这个会话可见. 临时表经常被用于存放一个操作的中间数据(数据处理的中间环节). 临时表由于不产生 ...

  5. sql中的小细节

    1.SUM与COUNT的区别 SUM是对符合条件的记录的数值列求和 COUNT 是对查询中符合条件的结果(或记录)的个数 2 select name as 姓名,tel  from...where.. ...

  6. HDU 4336:Card Collector(容斥原理)

    http://acm.split.hdu.edu.cn/showproblem.php?pid=4336 Card Collector Special Judge Problem Descriptio ...

  7. 6.shap以及selector的使用

    功能:相当于自定义一个模板 首先,要新建一个drawble文件夹 然后,再新建一个XML文件 在<shap></shap>中写内容 <corners/>圆角 < ...

  8. 训练集(train set) 验证集(validation set) 测试集(test set)

    转自:http://www.cnblogs.com/xfzhang/archive/2013/05/24/3096412.html 在有监督(supervise)的机器学习中,数据集常被分成2~3个, ...

  9. UVa 133,发放救济金

    沿用前一个题的思路: 用left记录剩下的点,直到全部选完. 这里我的问题是,我一直pos = (pos + f + n)%n,这里的问题是对于B点来说,开始的位置是1,就成了(1+(-1) +n) ...

  10. 单片机C语言开发学习笔记---动态的数码管

    在郭天祥的那本书中,有一个通过按键控制数码管的例子,在运行这个例子的时候,我发现当按键按下的时候,第一位数码管会熄掉,这是为什么呢? 后来在网上找到了原因,当我按下按键不松开的时候,接下来要运行的代码 ...