zoukankan      html  css  js  c++  java
  • 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!
    ");
            else printf("No!
    ");
        }
        return 0;
    }
    
    
    
     
  • 相关阅读:
    市场上 MLCC 226 电容现象
    什么是 PCB 的压适孔
    MLCC 电容的的 NP0 C0G 材质
    超时 CS-8610 中性笔
    压敏电阻报关相关信息
    锂电池充电的四个阶段
    FastAdmin 的 Bootstrap-Table 如何合并字段?
    从2012之殇到2013的思想极度动荡的这段人生路程….
    在页面上的输入框中即可以输入文字,又可以动态的插入图片的功能.
    由一条普通的link引用引发的无数问号,大家能回答的帮忙回答回答吧.
  • 原文地址:https://www.cnblogs.com/whdsunny/p/9838579.html
Copyright © 2011-2022 走看看