POJ 1113 Wall 求凸包

http://poj.org/problem?id=1113

不多说...凸包网上解法很多,这个是用graham的极角排序,也就是算导上的那个解法

其实其他方法随便乱搞都行...我只是测一下模板...

struct POINT{
    double x,y;
    POINT(double _x = 0, double _y = 0):x(_x),y(_y){};
};
POINT p[MAXN],s[MAXN];
double dist(POINT p1,POINT p2){
    return(sqrt((p1.x-p2.x) * (p1.x-p2.x) + (p1.y-p2.y) * (p1.y-p2.y)));
}
double multiply(POINT sp,POINT ep,POINT op){
    return (sp.x-op.x) * (ep.y-op.y) - (ep.x-op.x) * (sp.y-op.y);
}
bool ptcmp(POINT a,POINT b){    // 极角排序cmp p[]为全局变量
    if(multiply(a,b,p[0]) == 0) return dist(p[0],a) < dist(p[0],b);
    return (multiply(a,b,p[0]) > 0);
}
int Graham_scan(POINT p[],POINT s[],int n){ //  返回凸包点的个数
    int i,k = 0,top = 2;
    for(i = 1; i < n ; i++)     //  取y最小且x最小的点为凸包起点
        if((p[i].y < p[k].y) || ((p[i].y == p[k].y) && (p[i].x < p[k].x)))
            k = i;
    swap(p[0],p[k]);            //  起点设置为p[0]
    sort(p+1,p+n,ptcmp);        //  极角排序
    for(i = 0 ; i < 3 ; i++)
        s[i] = p[i];            //  前三个点入栈
    for(i = 3; i < n ; i++){
        while(multiply(p[i],s[top],s[top-1]) >= 0)
            top--;
        s[++top] = p[i];
    }
    return top + 1;
}
int main()
{
    int a,b,n;
    double r;
    while(~scanf("%d%lf",&n,&r)){
        for(int i = 0 ; i < n ; i++)
            scanf("%lf%lf",&p[i].x,&p[i].y);
        int len = Graham_scan(p,s,n);
        double sum = dist(s[len-1],s[0]);
        for(int i = 0 ; i < len-1 ; i++){
            sum += dist(s[i],s[i+1]);
        }
        sum += (PI*r*2);
        cout<<floor(sum+0.5)<<endl;
    }
    return 0;
}

 

posted @ 2013-08-04 20:17  Felix_F  阅读(223)  评论(0)    收藏  举报