您的位置:首页 > 其它

POJ 1113 WALL(凸包-计算几何)

2010-08-14 18:51 441 查看
题目大意:给出城堡的若干点,要求在其周围建围墙,使距离城堡>=L,并使长度最短。

思路:

求出若干点的凸包,每个边平行向外延伸L,断开处用圆弧连接,圆弧的端点连接原凸包顶点,则分别与两边垂直,则圆心角与内夹角互补。

设凸包为n边形,则凸包内角和为(n-2)*PI ,则凸包外所有圆心角和为n*PI-(n-2)*PI=2*PI,刚好为一半径为L的圆周长。

求凸包时 按y从小到大排 y相同按x从小到大排。

#include <iostream>
#include <cmath>
using namespace std;
const double PI=3.1415926536;
struct Point
{
int x,y;
};
Point P[1001],C[1001];
//求叉积
int cross(Point p1,Point p2,Point p3)
{
return (p2.x-p1.x)*(p3.y-p1.y)-(p2.y-p1.y)*(p3.x-p1.x);
}
double dis(Point p1,Point p2)
{
return sqrt(double(((p1.x-p2.x)*(p1.x-p2.x)+(p1.y-p2.y)*(p1.y-p2.y))));
}

int cmp(const void *a ,const void *b)
{
Point *c=(Point *)a;
Point *d=(Point *)b;
if(c->y == d->y)
return c->x-d->x;
else
return c->y-d->y;
}

int main()
{
int L,N,i,m,m1;
double ans;
while(scanf("%d%d",&N,&L)!=EOF)
{
for(i=0;i<N;i++)
scanf("%d%d",&P[i].x,&P[i].y);
qsort(P,N,sizeof(P[0]),cmp);
//左链
for(m=0,i=0;i<N;i++)
{
while(m>1 && cross(C[m-1],C[m-2],P[i])<=0)
m--;
C[m++]=P[i];
}
m1=m;
//右链
for(i=N-2;i>=0;i--)
{
while(m>m1 && cross(C[m-1],C[m-2],P[i])<=0)
m--;
C[m++]=P[i];
}
for(ans=0,i=0;i<m-1;i++)
ans+=dis(C[i],C[i+1]);
ans+=2*PI*L;
printf("%.0lf/n",ans);
}
return 0;
}
内容来自用户分享和网络整理,不保证内容的准确性,如有侵权内容,可联系管理员处理 点击这里给我发消息
标签: