POJ 1113 Wall(凸包)

博客原文地址:http://blog.csdn.net/xuechelingxiao/article/details/39023795


Wall


题目大意:给出多边形城堡的所有顶点,在外围建一圈城墙,城墙距离城堡的距离至少为L,求城墙的最小长度。


解题思路:其实所求问题可以转换成两部分,一部分是以多边形围城的凸包的长度,另一部分则是凸包向外扩L之后,剩下的部分会填补成一个整圆。


如图:












Source Code
Problem: 1113		User: 14110103069
Memory: 224K		Time: 0MS
Language: C++		Result: Accepted

    Source Code

    #include <stdio.h>
    #include <iostream>
    #include <algorithm>
    #include <math.h>
    using namespace std;

    const double eps = 1e-8;
    const double Pi = acos(-1.0);

    struct Point {
        double x, y;
    } P[1005], p[1005], convex[1005];

    int dcmp(double x) {
        return x < -eps ? -1 : x > eps;
    }
    double xmult(Point a, Point b, Point c){
        return (a.x-c.x)*(b.y-c.y)-(a.y-c.y)*(b.x-c.x);
    }
    double Distance(Point a, Point b){
        return sqrt((a.x-b.x)*(a.x-b.x)+(a.y-b.y)*(a.y-b.y));
    }
    bool cmp(Point a, Point b){
        if(dcmp(xmult(a, b, P[0])) == 0){
            return Distance(a, P[0]) < Distance(b, P[0]);
        }
        else {
            return dcmp(xmult(a, b, P[0])) > 0;
        }
    }
    int cmpp(Point a, Point b){
        if(a.x-b.x < eps)  return a.y-b.y < eps;
        else  return a.x-b.x < eps;
    }
    int Remove(int n){ //remove repeat points
        int m = 1;
        sort(p, p+n, cmpp);
        P[0] = p[0];
        for(int i = 1; i < n; ++i){
            if(!dcmp(p[i].x-p[i-1].x) == 0 ||
    !dcmp(p[i].y-p[i-1].y) == 0){
                P[m++] = p[i];
            }
        }
        return m;
    }
    int Graham(int n){
        int m = n;
        int s = 0, top = 1;
        for(int i = 0; i < m; ++i){
            if(P[i].y < P[s].y ||
    (P[i].y == P[s].y && P[i].x < P[s].x)){
                s = i;
            }
        }
        if(s != 0){
            Point tmp = P[0];  P[0] = P[s];  P[s] = tmp;
        }
        sort(P+1, P+m, cmp);
        convex[0] = P[0], convex[1] = P[1];
        for(int i = 2; i < m; ++i){
            while(top > 0 &&
    dcmp(xmult(convex[top], P[i], convex[top-1])) <= 0){
                //if need point on the convex hull,use <
    top--;
            }
            convex[++top] = P[i];
        }
        return top+1;
    }


    int main()
    {
        double r;
        int n;
        scanf("%d%lf", &n, &r);
        for(int i = 0; i < n; ++i) {
            scanf("%lf%lf", &P[i].x, &P[i].y);
        }
        int m = Graham(n);
        double ans = 0;
        for(int i = 0; i < m; ++i) {
            ans += Distance(convex[i], convex[(i+1)%m]);
        }
        ans += 2*Pi*r;
        printf("%.0f\n", ans);

        return 0;
    }






  • 0
    点赞
  • 0
    收藏
    觉得还不错? 一键收藏
  • 0
    评论
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值