书山有径勤为路>>>>>>>>

<<<<<<<<学海无涯苦作舟!

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;
}

 

 

posted on 2011-11-15 21:51  More study needed.  阅读(233)  评论(0编辑  收藏  举报

导航

书山有径勤为路>>>>>>>>

<<<<<<<<学海无涯苦作舟!