Time Limit: 1000MS | Memory Limit: 10000K | |
Total Submissions: 29116 | Accepted: 9744 |
Description
Input
Output
Sample Input
9 100 200 400 300 400 300 300 400 300 400 400 500 400 500 200 350 200 200 200
Sample Output
1628
Hint
Source
题意:给出平面上若干个点的坐标,让建一个环形围墙,把所有的点围在里面,且距所有点的距离不小于l。求围墙的最小长度。
分析:凸包周长+半径为l的圆周长。
#include <iostream> #include <string.h> #include <algorithm> #include <math.h> using namespace std; #define M 1000 int top; struct node { double x,y; }p[M],stack[M]; //计算两点间距离。 double L(node a,node b) { return sqrt((a.x-b.x)*(a.x-b.x)+(a.y-b.y)*(a.y-b.y)); } //计算叉积的大小。 double multi(node a,node b,node c) { return (a.x-c.x)*(b.y-c.y)-(b.x-c.x)*(a.y-c.y); } //计算左转还是右转,大于零就是左转,小于零就是右转。 int cmp(node a,node b) { if(multi(a,b,p[0])>0) return 1; if(multi(a,b,p[0])==0&&L(a,p[0])<L(b,p[0])) return 1; return 0; } //核心部分 void GS(node p[],node stack[],int n) { int i,k=0; node temp; for(i=0;i<n;i++) { if(p[i].y<p[k].y||((p[i].y==p[k].y)&&(p[i].x<p[k].x))) k=i; } temp=p[0]; p[0]=p[k]; p[k]=temp; sort(p+1,p+n,cmp); //p[0]已经是最小,没必要再对它进行排序。 top=2; //开始时栈里已经有3个元素。 stack[0]=p[0],stack[1]=p[1],stack[2]=p[2]; for(i=3;i<n;i++) { while(top>1&&multi(p[i],stack[top],stack[top-1])>=0) top--; //如果右转,栈顶元素出栈。 stack[++top]=p[i]; //找到左转,元素入栈。 } } int main() { double t; int n,i,m; while(scanf("%d%d",&n,&m)!=EOF) { t=0; memset(p,0,sizeof(p)); memset(stack,0,sizeof(stack)); for(i=0;i<n;i++) { scanf("%lf %lf",&p[i].x,&p[i].y); //有小数,用double。 } GS(p,stack,n); stack[top+1]=stack[0]; //最后一个和第一个也有距离要加。 for(i=0;i<=top;i++) { t+=L(stack[i],stack[i+1]); } t=t+2*m*3.1415926; printf("%.0lf\n",t); } return 0; }
POJ 1113 Wall (凸包),布布扣,bubuko.com
原文地址:http://blog.csdn.net/qq2256420822/article/details/37728247