版权声明:本文为博主原创文章,未经博主允许不得转载。 https://blog.csdn.net/Masqueradey/article/details/52702977
这道题是给定点集,求出凸包,然后在外面构筑一个城墙,使凸包每一点到围墙距离小于一个给定的值L。最终可以等价于凸包周长之和再加上以L为半径的圆的周长。
代码:
#include<iostream>
#include<algorithm>
#include<cmath>
#include<cstdlib>
using namespace std;
#define maxn 2000
const double PI=3.1415926;
struct point{
int x,y;
}points[maxn],s[maxn];
int top,N,L;
double dis(point a,point b){
return sqrt((a.x-b.x)*(a.x-b.x)+(a.y-b.y)*(a.y-b.y));
}
int multiply(point a,point b,point c){
return (b.x-a.x)*(c.y-a.y)-(b.y-a.y)*(c.x-a.x);
}
bool cmp(point a , point b){
int m;
m = multiply(points[1],a,b) ;
if(m>0)return 1;
else if(m==0&&(dis(points[1],a)<dis(points[1],b)))return 1;
return 0;
}
void tubao(){
int i,j;
s[1].x=points[1].x;
s[1].y=points[1].y;
s[2].x=points[2].x;
s[2].y=points[2].y;
top=2;
for(i=3;i<=N;i++)
{
for(;top>=2;)
{
if(multiply(s[top-1],s[top],points[i])<=0){top--;continue;}
break;
}
s[++top]=points[i];
}
return;
}
int main(){
ios::sync_with_stdio(false);
int i,j,pos=1;
double sum=0;
cin>>N>>L;
for(i=1;i<=N;i++)cin>>points[i].x>>points[i].y;
for(i=2;i<=N;i++)
{
if(points[i].x<points[pos].x){pos=i;continue;}
else if(points[i].x==points[pos].x&&points[i].y<points[pos].y){pos=i;continue;}
}
swap(points[1],points[pos]);
sort(points+2,points+N+1,cmp);
tubao();
for(i=1;i<top;i++)sum+=dis(s[i],s[i+1]);
sum+=dis(s[1],s[top]);
sum+=2*PI*L;
cout<<(int)(sum+0.5)<<endl;
system("pause");
return 0;
}