poj 3304——Segments

大致題意:給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;
}

 

 

發表評論
所有評論
還沒有人評論,想成為第一個評論的人麼? 請在上方評論欄輸入並且點擊發布.
相關文章