zoukankan      html  css  js  c++  java
  • SGU 124. Broken line 射线法 eps的精准运用,计算几何 难度:3

    124. Broken line

    time limit per test: 0.25 sec. 
    memory limit per test: 4096 KB

     

    There is a closed broken line on a plane with sides parallel to coordinate axes, without self-crossings and self-contacts. The broken line consists of K segments. You have to determine, whether a given point with coordinates (X0,Y0) is inside this closed broken line, outside or belongs to the broken line.

     

    Input

    The first line contains integer K (4 Ј K Ј 10000) - the number of broken line segments. Each of the following N lines contains coordinates of the beginning and end points of the segments (4 integerxi1,yi1,xi2,yi2all numbers in a range from -10000 up to 10000 inclusive). Number separate by a space. The segments are given in random order. Last line contains 2 integers X0 and Y0 - the coordinates of the given point delimited by a space. (Numbers X0, Y0 in a range from -10000 up to 10000 inclusive).

     

    Output

    The first line should contain:

    INSIDE - if the point is inside closed broken line,

    OUTSIDE - if the point is outside,

    BORDER - if the point belongs to broken line.

     

    Sample Input

    4
    0 0 0 3
    3 3 3 0
    0 3 3 3
    3 0 0 0
    2 2
    

     

    Sample Output

    INSIDE
    
    因为线条简单,所以随便射线法就行了,射线的"稍微移动",也就是对目标区间做半开半闭处理,可以用eps实现,很巧妙 
    #include <cstdio>
    #include <cstring>
    #include <cmath>
    #include <algorithm>
    using namespace std;
    const double eps=1e-9;
    struct pnt{
        double x,y;
        pnt():x(0),y(0){}
        pnt(double tx,double ty):x(tx),y(ty){}
    }p[20000][2],aim;
    int n;
    bool onborder(int ind){
        if(fabs(p[ind][0].y-p[ind][1].y)>eps){
            int low=min(p[ind][0].y,p[ind][1].y);
            int high=max(p[ind][0].y,p[ind][1].y);
            if(fabs(aim.x-p[ind][0].x)>eps)return false;
            return aim.y>low+eps&&aim.y+eps<high;
        }
        else {
            int low=min(p[ind][0].x,p[ind][1].x);
            int high=max(p[ind][0].x,p[ind][1].x);
            if(fabs(aim.y-p[ind][0].y)>eps)return false;
            return aim.x+eps>low&&aim.x<high+eps;
        }
    }
    bool cross(int ind){
        if(fabs(p[ind][0].y-p[ind][1].y)<eps)return false;
        if(aim.x+eps>p[ind][0].x)return false;
        int low=min(p[ind][0].y,p[ind][1].y);
        int high=max(p[ind][0].y,p[ind][1].y);
        return aim.y+eps>low&&eps+aim.y<high;//ATTENTION aim.y>=low&&aim<high
    }
    
    int main(){
        scanf("%d",&n);
        for(int i=0;i<n;i++){
            scanf("%lf%lf%lf%lf",&p[i][0].x,&p[i][0].y,&p[i][1].x,&p[i][1].y);
        }
        scanf("%lf%lf",&aim.x,&aim.y);
        int cnt=0;
        for(int i=0;i<n;i++){
            if(onborder(i)){puts("BORDER");return 0;}
            else if(cross(i))cnt++;
        }
        if(cnt&1)puts("INSIDE");
        else puts("OUTSIDE");
        return 0;
    }
    

      

  • 相关阅读:
    linux——进程管理
    linux——软件管理
    linux——压缩打包
    linux——输入输出
    linux——ACL控制
    linux——特殊权限
    linux——基本权限
    linux——用户管理
    单源最短路spfa(队列优化)
    getline读取
  • 原文地址:https://www.cnblogs.com/xuesu/p/4009478.html
Copyright © 2011-2022 走看看