您的位置:首页 > 其它

POJ 1113 Wall(凸包)

2014-09-03 10:42 399 查看
博客原文地址:/article/2633957.html

Wall

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



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



如图:








#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;//Remove(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;
}
内容来自用户分享和网络整理,不保证内容的准确性,如有侵权内容,可联系管理员处理 点击这里给我发消息
标签: