zoukankan      html  css  js  c++  java
  • 多边形

    A histogram is a simple rectilinear polygon whose boundary consists of two chains such that the upper
    chain is monotone with respect to the horizontal axis and the lower chain is a horizontal line segment,
    called the base segment (See Figure 1).
    Figure 1. A histogram and its base segment (v0, v1)
    Let P be a histogram specified by a list (v0, v1, . . . , vn−1) of vertices in the counterclockwise order
    along the boundary such that its base segment is (v0, v1). An edge ei
    is a line segment connecting two
    vertices vi and vi+1, where i = 0,1, . . . , n − 1 and vn = v0.
    A path inside P is a simple path which does not intersect the exterior of P. The length of the path
    is defined as the sum of Euclidean length of the line segments of the path. The distance between two
    points p and q of P is the length of the shortest path inside P between p and q. Your task is to find
    the distance between v0 and each point of a given set S of points on the boundary of P. A point of
    the set S is denoted by p(k, d) which represents a point q on the edge ek such that d is the distance
    between vk and q.
    In the histogram of Figure 1, the shortest path between v0 and q1 = p(10,2) is a polygonal chain
    connecting v0, v14, v12 and q1 in that order, and its length is 8.595242. The shortest path between v0
    and q2 = p(1,1) is a segment directly connecting v0 and q2 with length 15.033296.
    Given a histogram P with n vertices and a set S of m points on the boundary of P, write a program
    to find the distances between v0 and all points of S.
    Input
    Your program is to read from standard input. The input consists of T test cases. The number of test
    cases T is given in the first line of the input. Each test case starts with a line containing an integer,
    n (4 ≤ n ≤ 100,000), where n is the number of vertices of a histogram P = (v0, v1, . . . , vn−1). In
    the following n lines, each of the n vertices of P is given line by line from v0 to vn−1. Each vertex is
    represented by two numbers, which are the x-coordinate and the y-coordinate of the vertex, respectively.
    Each coordinate is given as an integer between 0 and 1,000,000, inclusively. Notice that (v0, v1) is the
    base segment. The next line contains an integer m (1 ≤ m ≤ 100,000) which is the size of a set S given
    as your task. In the following m lines. Each point p(k, d) of S is given line by line, and is represented
    by two integers k and d, where 0 ≤ k ≤ n − 1 and 0 ≤ d < the length of edge ek. All points in the set
    S are distinct.
    Output
    Your program is to write to standard output. Print exactly one line for each test case. The line should
    contain exactly one real value which is the sum of the distances between v0 and all points of S. Your
    output must contain the first digit after the decimal point, rounded off from the second digit. If each
    result is within an error range, 0.1, it will be considered correct. The Euclidean distance between two
    points p = (x1, y1) and q = (x2, y2) is √
    (x2 − x1)
    2 + (y2 − y1)
    2.
    The following shows sample input and output for two test cases.
    Sample Input
    2
    16
    0 0
    15 0
    15 4
    13 4
    13 6
    10 6
    10 2
    7 2
    7 5
    6 5
    6 7
    3 7
    3 3
    2 3
    2 1
    0 1
    2
    10 2
    1 1
    8
    100000 100000
    400000 100000
    400000 200000
    300000 200000
    300000 300000
    200000 300000
    200000 200000
    100000 200000
    8
    1 0
    2 0
    3 0
    4 0
    5 0
    6 0
    7 0
    1 50000
    Sample Output
    23.6
    1909658.1

    链接:给你一个n边形,他的每条边都平行于x轴或y轴,从最左下角顶点开始,逆时针一次给出n变形上的端点坐标,然后再给你n变形上的m个点,求最左下角的点到这m个点的最短距离之和,距离要求两点连线不能与n变形的边在内部相交。

    #include <cstdio>
    #include <iostream>
    #include <algorithm>
    #include <cstring>
    #include <iostream>
    #include <cmath>
    #include <queue>
    #include <vector>
    #define MM(a,b) memset(a,b,sizeof(a));
    #define inf 0x3f3f3f3f
    using namespace std;
    typedef long long ll;
    #define CT continue;
    #define SC scanf
    const int N=1e5+10;
    int cas,n,m;
    
    double f[N];
    struct Point{
        double x,y;int k,d,flag;
        void read(){
            scanf("%lf%lf",&x,&y);
        }
    }p[2*N],c[2*N];
    
    void init(int i,int k,int d)
    {
        p[i]=p[k];
        if(p[k].y<p[k+1].y) p[i].y=p[k].y+d;
        if(p[k].y>p[k+1].y) p[i].y=p[k].y-d;
        if(p[k+1].x>p[k].x) p[i].x=p[k].x+d;
        if(p[k+1].x<p[k].x) p[i].x=p[k].x-d;
        p[i].k=k;
        p[i].d=d;
        p[i].flag=1;
    }
    
    double dis(Point a)
    {
        return sqrt(a.x*a.x+a.y*a.y);
    }
    
    Point operator-(Point a,Point b)
    {
        return (Point){a.x-b.x,a.y-b.y,0,0,0};
    }
    
    double cross(Point a,Point b)
    {
        return a.x*b.y-b.x*a.y;
    }
    
    bool cmp(Point a,Point b)
    {
        if(a.k!=b.k) return a.k>b.k;
        else return a.d>b.d;
    }
    
    int main()
    {
        SC("%d",&cas);
        while(cas--)
        {
              SC("%d",&n);
              for(int i=0;i<n;i++) {
                    p[i].read();
                    p[i].k=i;
                    p[i].d=0;
                    p[i].flag=0;
              }
              SC("%d",&m);
              for(int i=1;i<=m;i++){
                 int k,d;
                 SC("%d%d",&k,&d);
                 init(i+n-1,k,d);
              }
              sort(p+1,p+n+m,cmp);
              double ans=0;
              int cnt=1;
              c[1]=p[0];
              for(int i=1;i<n+m;i++){
                  while(cnt>1&&cross(p[i]-c[cnt-1],c[cnt]-c[cnt-1])>=0) cnt--;
                  c[++cnt]=p[i];
                  f[cnt]=f[cnt-1]+dis(c[cnt]-c[cnt-1]);
                  if(p[i].flag) {
                        ans+=f[cnt];
                  }
              }
              printf("%.1f
    ",ans);
        }
        return 0;
    }
    

      解决:构建一个凸包

  • 相关阅读:
    echarts
    联合省选2021游记
    高维 FWT 学习笔记
    Unicode简介
    mac安装brew
    原生JS实现分页跳转
    Kubernetes Pod Probes 探针解析
    Kubernetes Secrets
    Kubernetes Container lifecycle hooks
    个人作业1——四则运算题目生成程序(基于java)
  • 原文地址:https://www.cnblogs.com/smilesundream/p/5793698.html
Copyright © 2011-2022 走看看