POJ 1113 凸包 graham


题目:http://poj.org/problem?id=1113
大意:求出凸包的周长,再加上一个圆的周长就是本问题的答案。

这个问题没有任何的难度,直接采用现成的模板就可以了。
View Code
#include "iostream"

#include "cstdio"

#include "cmath"

#include "algorithm"

using namespace std;

const double PI=acos(-1.0);

const int size=1005;

const double eps=1e-8;

struct Point

{

    int x, y;

}p[size];

int s[size], top;

int zfcmp(int d)

{

    if(abs(d) < eps) return 0;

    return d>0?1:-1;

}

bool cmp(Point p1, Point p2)

{

    if(p1.y==p2.y) return p1.x<p2.x; //这里一定是p1.x<p.x, 不能是p1.x-p2.x

    else return p1.y<p2.y;

}

int cross(Point c, Point a, Point b) //c是s[top-1], a是p[i], b是s[top]

{

    return (a.x-c.x)*(b.y-c.y)-(b.x-c.x)*(a.y-c.y);

}

double dis(Point a, Point b)

{

    return sqrt(0.0+(a.x-b.x)*(a.x-b.x)+(a.y-b.y)*(a.y-b.y));

}

void graham_scam(int n)

{

    int i, t;

    sort(p, p+n, cmp);

    top = -1;

    s[++top] = 0;

    s[++top] = 1;

    for(i=2; i<n; i++)

    {

        while(top>=1 && zfcmp( cross(p[s[top-1]], p[i], p[s[top]]) )>=0 )

            top--;

        s[++top] = i;

    }

    t = top;

    s[++top] = n-2;

    for(i=n-3; i>=0; i--)

    {

        while(top>=t+1 && zfcmp( cross(p[s[top-1]], p[i], p[s[top]]) )>=0 )

            top--;

        s[++top] = i;

    }

}

int main()

{

    int i, n, l;

    double ans;

    while(cin>>n>>l)

    {

        for(i=0; i<n; i++)

            cin>>p[i].x>>p[i].y;

        graham_scam(n);

        ans = 0.0;

        for(i=0; i<top; i++)

            ans+=dis(p[s[i]], p[s[i+1]]);

        ans+=2*PI*l;

        printf("%0.f\n",ans);

    }

    return 0;

}
 
  

 

 

你可能感兴趣的:(poj)