POJ 3304 Segments(直线)

题目:

Description

Given n segments in the two dimensional space, write a program, which determines if there exists a line such that after projecting these segments on it, all projected segments have at least one point in common.

Input

Input begins with a number T showing the number of test cases and then, T test cases follow. Each test case begins with a line containing a positive integer n ≤ 100 showing the number of segments. After that, n lines containing four real numbers x1 y1 x2 y2 follow, in which (x1y1) and (x2y2) are the coordinates of the two endpoints for one of the segments.

Output

For each test case, your program must output "Yes!", if a line with desired property exists and must output "No!" otherwise. You must assume that two floating point numbers a and b are equal if |a - b| < 10-8.

Sample Input

3
2
1.0 2.0 3.0 4.0
4.0 5.0 6.0 7.0
3
0.0 0.0 0.0 1.0
0.0 1.0 0.0 2.0
1.0 1.0 2.0 1.0
3
0.0 0.0 0.0 1.0
0.0 2.0 0.0 3.0
1.0 1.0 2.0 1.0

Sample Output

Yes!
Yes!
No!

题意:给出n条线段 判断是否存在一条直线 使所有线段在这条直线上的投影都有至少一个公共点
思路:经过一些奇妙的转变 可以将题目转换为从所有线段中任选两个端点组成的直线是否可以穿过所有的线段 需要对选取的两个端点进行去重

代码:
#include <iostream>
#include <cstdio>
#include <cstdlib>
#include <cmath>
#include <string>
#include <cstring>
#include <algorithm>

using namespace std;
typedef long long ll;
typedef unsigned long long ull;
const int inf=0x3f3f3f3f;
const int maxn=110;
const double eps=1e-8;
int t,n;
double x,y,xx,yy;

int dcmp(double x){
    if(fabs(x)<eps) return 0;
    if(x<0) return -1;
    return 1;
}

struct Point{
    double x,y;
    Point(){}
    Point(double _x,double _y){
        x=_x,y=_y;
    }
    Point operator + (const Point &b) const {
        return Point(x+b.x,y+b.y);
    }
    Point operator - (const Point &b) const {
        return Point(x-b.x,y-b.y);        
    }
    double operator * (const Point &b) const {
        return x*b.x+y*b.y;
    }
    double operator ^ (const Point &b) const {
        return x*b.y-y*b.x;
    }
};

struct Line{
    Point s,e;
    Line(){}
    Line(Point _s,Point _e){
        s=_s,e=_e;
    }
}line[maxn];

double xmult(Point p0,Point p1,Point p2){
    return (p1-p0)^(p2-p0);
}

bool Seg_inter_line(Line l1,Line l2){
    return dcmp(xmult(l2.s,l1.s,l1.e))*dcmp(xmult(l2.e,l1.s,l1.e))<=0;
}

double dist(Point a,Point b){
    return sqrt((b-a)*(b-a));
}

bool check(Line l1,int n){
    if(dcmp(dist(l1.s,l1.e))==0) return false;  //判断重复点
    for(int i=0;i<n;i++)
        if(Seg_inter_line(l1,line[i])==false)
            return false;
    return true;
}

int main(){
    scanf("%d",&t);
    while(t--){
        scanf("%d",&n);
        for(int i=0;i<n;i++){
            scanf("%lf%lf%lf%lf",&x,&y,&xx,&yy);
            line[i]=Line(Point(x,y),Point(xx,yy));
        }
        bool flag=false;
        for(int i=0;i<n;i++)
            for(int j=0;j<n;j++)
                if(check(Line(line[i].s,line[j].s),n) || check(Line(line[i].e,line[j].e),n) || check(Line(line[i].s,line[j].e),n) || check(Line(line[i].e,line[j].s),n)){
                    flag=true;
                    break;
                }
        if(flag) printf("Yes!\n");
        else printf("No!\n");
    }
    return 0;
}

 

 
posted @ 2018-10-23 19:07  周园顾  阅读(132)  评论(0编辑  收藏  举报