POJ3304计算几何

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

题意:实际上就是问有没有一条直线能与所有给定的线段有交点。

思路:用给定的线段的端点枚举所有可能的直线(要判断两条线段端点是不是重合),然后判断这个直线是不是与所有的线段有交点

判断直线与线段是否相交的方法:(就用上两篇博客中的判断一个点在一条直线的左边还是右边。)两个向量以点b为公共点,如果向量bg在向量ba的逆时针方向(左边),那么(g-b)*(a-b)<0(也就是上两篇说的x1*y2-x2*y1<0),再设点a(x1,x2),点b(x2,y2),点g(x,y),那么就有(x-x2)*(y1-y2)-(x1-x2)*(y-y2)<0;如果在右边就>0;所以如果直线与线段相交,那么一定有线段两端在直线左右,所以一个<0一个>0相乘必定小于0,问题解决。

AC代码:

 
#include<iostream>
#include<cstdio>
#include<cstring>
#include<cstdlib>
#include<algorithm>
#include<cmath>
using namespace std;
#define EPS 1e-8
struct node
{
    float  x1,y1,x2,y2;
};
node setting[110];
int n;

float distance(float x1,float y1,float x2,float y2)
{
    return sqrt((x1-x2)*(x1-x2)+(y1-y2)*(y1-y2));
}

float corss(float x1,float y1,float x2,float y2,float x,float y)
{
    return ((x-x2)*(y1-y2)-(x1-x2)*(y-y2));
}

int judge(float x1,float y1,float x2,float y2)
{
    if(distance(x1,y1,x2,y2)<EPS)return 0;
    for(int i=1;i<=n;i++)
        if(corss(x1,y1,x2,y2,setting[i].x1,setting[i].y1)*
           corss(x1,y1,x2,y2,setting[i].x2,setting[i].y2)>EPS)
           return 0;
    return 1;
}

int main()
{
    int t;
    int ans;
    scanf("%d",&t);
    while(t--)
    {
        scanf("%d",&n);
        for(int i=1;i<=n;i++)
        {
            scanf("%f%f%f%f",&setting[i].x1,&setting[i].y1,&setting[i].x2,&setting[i].y2);
        }
        if(n==1)
        {
            printf("Yes!\n");
            continue;
        }
        ans=0;
        for(int i=1;i<=n&&!ans;i++)
            for(int j=i+1;j<=n&&!ans;j++){
                if(judge(setting[i].x1,setting[i].y1,setting[j].x1,setting[j].y1)||
                   judge(setting[i].x1,setting[i].y1,setting[j].x2,setting[j].y2)||
                   judge(setting[i].x2,setting[i].y2,setting[j].x1,setting[j].y1)||
                   judge(setting[i].x2,setting[i].y2,setting[j].x2,setting[j].y2))
                    ans=1;
            }
        if(ans)printf("Yes!\n");
        else printf("No!\n");
    }
    return 0;
}
View Code

 

posted @ 2013-08-08 11:48  拼搏今朝 努力奋进  阅读(196)  评论(0)    收藏  举报