欢迎您访问程序员文章站本站旨在为大家提供分享程序员计算机编程知识!
您现在的位置是: 首页

poj 3304——Segments

程序员文章站 2022-04-02 17:05:38
...

大致题意:给n条线段,判断是否存在一条线段,使得所有的线段在它上面的投影是否有公共交点。

大致思路:既然是投影,那很明显在纸上画一下就知道,以某条线段作为x轴建立直角坐标系,那就可以轻松的

画出每条线段在x轴上的投影,也就很容易就知道,判断投影有没有公共点,其实就是看有没有一条直线可以穿过所有的线段。

这里其实稍微跳了一点,但是画图就很容易知道我在说什么。看题目的数据范围n为100,所以暴力枚举任意两个的端点,判断这两个端点的直线是否可以穿过所有的线段。注:枚举的时候,如果两个端点的距离小于1e-8,就认为是同一个点,这次枚举的端点不算。

同时,通过上面的分析,大胆猜测口嗨一下,如果不考虑线段旋转的精度误差,应该可以枚举旋转线段,暴力判断所有线段的左端点的x坐标都小于min(所有线段的右端点的x坐标)。瞎吹一会,不要在意。

最后,代码:

#include<iostream>
#include<stdio.h>
#include<math.h>
using namespace std;
int n;
struct line
{
    double x1,y1,x2,y2;
}lines[120];
double multiple_cross(double x1,double y1,double x2,double y2)
{
    return x1*y2-x2*y1;
}
bool check(line a,line b)
{
    double w,z;
    w=multiple_cross(a.x1-b.x1,a.y1-b.y1,b.x2-b.x1,b.y2-b.y1);
    z=multiple_cross(a.x2-b.x1,a.y2-b.y1,b.x2-b.x1,b.y2-b.y1);
    if(w*z<=0)
        return true;
    return false;
}
bool judge(line ac)
{
    if(sqrt((ac.x1-ac.x2)*(ac.x1-ac.x2)+(ac.y1-ac.y2)*(ac.y1-ac.y2))<1e-8)
        return false;
    bool flag=true;
    for(int i=0;i<n;++i)
    {
        if(!check(lines[i],ac))
            flag=false;
    }
    return flag;
}
int main()
{
    int T;
    scanf("%d",&T);
    while(T--)
    {
        scanf("%d",&n);
        for(int i=0;i<n;++i)
        {
            scanf("%lf %lf %lf %lf",&lines[i].x1,&lines[i].y1,&lines[i].x2,&lines[i].y2);
        }
        if(n==1||n==2)
        {
            printf("Yes!\n");
            continue;
        }
        line ac;
        bool flag=false;
        for(int i=0;i<n;++i)
        {
            for(int j=i+1;j<n;++j)
            {
                ac.x1=lines[i].x1,ac.y1=lines[i].y1;
                ac.x2=lines[j].x1,ac.y2=lines[j].y1;
                if(judge(ac))
                {
                    flag=true;
                }
                ac.x2=lines[j].x2,ac.y2=lines[j].y2;
                if(judge(ac))
                {
                    flag=true;
                }
                ac.x1=lines[i].x2,ac.y1=lines[i].y2;
                if(judge(ac))
                {
                     flag=true;
                }
                ac.x2=lines[j].x1,ac.y2=lines[j].y1;
                if(judge(ac))
                {
                    flag=true;
                }
            }
        }
        if(flag)
            printf("Yes!\n");
        else
            printf("No!\n");
    }
    return 0;
}