您的位置:首页 > 其它

POJ 1113 WALL (凸包问题)

2011-08-09 15:26 375 查看
求凸包,算周长,加上2*Pi*r即得所求

//============================================================================

// Name : hello.cpp

// Author : key

// Version : 8

// Copyright : Your copyright notice

// Description : Hello World in C++, Ansi-style

//============================================================================

#include <iostream>

#include <cstring>

#include <cstdio>

#include <cmath>

#include <queue>

#include <stack>

#include <set>

#include <string>

#include <algorithm>

using namespace std;

#define NUM_INF 0XFFFFF

/*==================================================*\

| Graham 求凸包 O(N * logN)

| CALL: nr = graham(pnt, int n, res); res[]为凸包点集;

\*==================================================*/

struct point {

double x, y;

}pnt[1010],res[1010];

bool mult(point sp, point ep, point op){

return (sp.x - op.x) * (ep.y - op.y)

>= (ep.x - op.x) * (sp.y - op.y);

}

bool operator < (const point &l, const point &r){

return l.y < r.y || (l.y == r.y && l.x < r.x);

}

int graham(int n){

int i, len, k = 0, top = 1;

sort(pnt, pnt + n);

if (n == 0) return 0; res[0] = pnt[0];

if (n == 1) return 1; res[1] = pnt[1];

if (n == 2) return 2; res[2] = pnt[2];

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

while (top && mult(pnt[i], res[top], res[top-1]))

top--;

res[++top] = pnt[i];

}

len = top; res[++top] = pnt[n - 2];

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

while (top!=len && mult(pnt[i], res[top],

res[top-1])) top--;

res[++top] = pnt[i];

}

return top; // 返回凸包中点的个数

}

double dis(point a,point b)

{

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

}

int main()

{

int n;

double r;

int i;

double Pi = acos(-1);

double sum;

scanf("%d%lf",&n,&r);

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

{

scanf("%lf%lf",&pnt[i].x,&pnt[i].y);

}

n = graham(n);

sum = dis(res[0],res[n-1]);

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

{

sum += dis(res[i],res[i-1]);

}

printf("%.0f\n",sum+Pi*(2.0*r));

return 0;

}
内容来自用户分享和网络整理,不保证内容的准确性,如有侵权内容,可联系管理员处理 点击这里给我发消息
标签: