Segments----是否存在直线与所有线段相交

来源:互联网 发布:js 怎么生成min.js 编辑:程序博客网 时间:2024/06/03 16:46

题目:http://acm.hdu.edu.cn/showproblem.php?pid=3492

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

注:这两题基本上是一样的,题意都是,所有线段在某条直线的投影有公共点,问:这条直线是否存在。

所有线段在某条直线的投影有公共点   等价于   所有线段与该条直线的垂线相交。

另外该直线存在的话一定会存在通过两条线段端点的直线。

枚举两两线段的组成的四条直线,看看该条直线是否与所有线段都相交。

注2:在判断某条直线是否与所有线段相交时,使用叉积,但poj的那一题要注意精度,

double cross( point a, point b,point c)  //ac{    return (b.x-a.x)*(c.y-a.y)-(b.y-a.y)*(c.x-a.x);}

double cross( point a, point b,point c) //wa{    return (b.x-a.x)*c.y-b.x*a.y-(b.y*c.x-b.y*a.x-a.y*c.x);   //把a.x*a.y约去,合并}
源代码:
#include  <stdio.h>#include <math.h>#define exp 1e-10#define N 405typedef  struct{    double x,y;}point;point p[N],p1[N];int n,cas,flag;double cross(point a,point b,point c){    return (b.x-a.x)*(c.y-a.y)-(b.y-a.y)*(c.x-a.x);}double dist(point a,point b){    return sqrt((a.x-b.x)*(a.x-b.x)+(a.y-b.y)*(a.y-b.y));}int judge(point a,point b){    if(dist(a,b)<exp)   return 0;    for(int i=0;i<n;i++)    if(cross(a,b,p[i])*cross(a,b,p1[i])>exp)  return 0;    return 1;}int solve(){    int flag=0,cnt=0;    for(int i=0;i<n;i++)     if(p[i].x==p[0].x&&p[i].y==p[0].y&&p1[i].x==p1[0].x&&p1[i].y==p1[0].y)       cnt++;    if(cnt==n)  return 1;    for(int i=0;i<n;i++)      {          for(int j=i+1;j<n;j++)          {              if(judge(p[i],p[j])||judge(p[i],p1[j])||judge(p1[i],p[j])||judge(p1[i],p1[j]))               {                   flag=1;  break;               }         }         if(flag)   break;      }    return flag;}int main(){    scanf("%d",&cas);    while(cas--)    {        scanf("%d",&n);        for(int i=0;i<n;i++)          scanf("%lf %lf %lf %lf",&p[i].x,&p[i].y,&p1[i].x,&p1[i].y);        flag=solve();        if(flag)  printf("Yes\n");        else  printf("No\n");    }    return 0;}




原创粉丝点击