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;
    }
    
    
    
     
  • 相关阅读:
    UVA 12901 Refraction 折射 (物理)
    UVA 12898
    UVA 690 PipelineScheduling 位运算+dfs+剪枝
    UVA1602 Lattice Animals 网格动物 (暴力,STL)
    UVA 810 A Dicey Promblem 筛子难题 (暴力BFS+状态处理)
    UVA 1600 Patrol Robert 巡逻机器人 (启发搜索BFS)
    UVA 536 TreeRocvery 树重建 (递归)
    二分查找
    OI记忆口诀
    OI经典语录
  • 原文地址:https://www.cnblogs.com/whdsunny/p/9838579.html
Copyright © 2011-2022 走看看