poj 3304 Segments(利用叉积求是否存在直线与所给线段相交)

来源:互联网 发布:数据库物理模型主键 编辑:程序博客网 时间:2024/05/01 04:46

//以下为原blog搬迁过来的内容

【题目大意】:给出n条线段,问你是否存在一条直线,使得每个线段与该直线至少有一个交点。


【解题思路】:没有思路,没有思路,还是没有思路。然后开始无止境的yy。 因为点的个数比较小,感觉n^3可以过,就开始yy枚举直线。一开始以为单纯的枚举之后就可以了,后来才发现要将左右线段投影到枚举出的直线上,取其相互覆盖的部分做垂线,这条线才是正解。

所以我们所要做的就是枚举假象中这条垂线,然后用叉积判断线段与之间的相交情况就可以了。

注意题目是坐标点的x,y的差分别小于1e-8,做的时候做成距离了,wa了一次


【代码】:

#include <iostream>#include <cstdio>#include <cstring>#include <algorithm>#include <vector>#include <queue>#include <cmath>#include <string>#include <cctype>#include <map>#include <iomanip>                   using namespace std;                   #define eps 1e-8#define pi acos(-1.0)#define inf 1<<30#define pb push_back#define lc(x) (x << 1)#define rc(x) (x << 1 | 1)#define lowbit(x) (x & (-x))#define ll long long#define maxn 210;struct Point{    double x,y;    Point() {}    Point(double a,double b)    {        x=a,y=b;    }}point[maxn];inline int sig(double k){    return k<-eps?-1:k>eps;}inline double det(double x1, double y1, double x2, double y2){    return x1*y2-x2*y1;}inline double xmult(Point o,Point a,Point b){    return det(a.x-o.x,a.y-o.y,b.x-o.x,b.y-o.y);}int main(){    int cas,n;    scanf("%d",&cas);    while(cas--)    {        scanf("%d",&n);        double tp1,tp2,tp3,tp4;        for(int i=1;i<=n;i++)        {            scanf("%lf%lf%lf%lf",&tp1,&tp2,&tp3,&tp4);            point[2*i-1]=Point(tp1,tp2);            point[2*i]=Point(tp3,tp4);        }        bool flag=false;        for(int i=1;i<=2*n&&flag==false;i++)        {            for(int j=1;j<=2*n;j++)            {                Point p,q;                p=point[i];                q=point[j];                if(sig(p.x-q.x)==0 && sig(p.y-q.y)==0) continue;                int l;                for(l=1;l<=n;l++)                    if(xmult(q,point[2*l-1],p)*xmult(q,point[2*l],p)>eps)                    {                        break;                    }                if(2*l-1>=2*n) {flag=true; break;}            }        }        if (flag==true) printf("Yes!\n");            else printf("No!\n");    }    return 0;}


原创粉丝点击