凸包计算_POJ1113

写在前面

题目中除了要计算凸包之外,还要求修理的城墙要和宫殿之间的距离不小于L,那么也就是相对于宫殿长度之外,多了一个一L为半径的圆的距离,所以题目就得以解决

POJ1113

程序

#include <iostream>
#include <algorithm>
#include <cstdio>
#include <cmath>

using namespace std;
typedef long long ll;
const int N = 1500;
const double PI = acos(-1.0);
struct Point{
    int x,y;
}a[N],p[N];
int n,tot,l;

double dis(const Point &p1,const Point &p2)
{
    return (double)(p2.x - p1.x) * (p2.x - p1.x) + (p2.y - p1.y) * (p2.y - p1.y);
}

int multi(const Point &p0,const Point &p1, const Point &p2)
{
    return (p1.x - p0.x) * (p2.y - p0.y) - (p2.x - p0.x) * (p1.y - p0.y);
}

bool cmp(const Point &p1,const Point &p2)
{
    int x = multi(a[0],p1,p2);
    if(x > 0 || (x == 0 && dis(a[0],p1) < dis(a[0],p2))) return 1;
    return 0;
}

void Graham()
{
    int k = 0;
    for(int i = 1;i < n;i ++)
        if(a[i].y < a[k].y || (a[i].y == a[k].y && a[i].x < a[k].x)) k = i;
    if(k != 0)
        swap(a[0],a[k]);
    sort(a+1, a+n, cmp);
    tot = 1, p[0] = a[0], p[1] = a[1];
    for(int i = 2;i < n;i ++)
    {
        while(tot && multi(p[tot-1],p[tot],a[i]) <= 0) tot--;
        p[++tot] = a[i];
    }
}
int main()
{
    scanf("%d%d",&n,&l);
    for(int i = 0;i < n;i ++)
        scanf("%d%d",&a[i].x,&a[i].y);
    Graham();
    double Len = sqrt(dis(p[0],p[tot]));
    for(int i = 0;i < tot;i ++)
        Len += sqrt(dis(p[i],p[i + 1]));
    Len += 2 * PI * l;
    printf("%d\n",(int)(Len+0.5));
}

猜你喜欢

转载自blog.csdn.net/li1615882553/article/details/84134230