http://poj.org/problem?id=1113
题目大意:现在要给n个点,让你修一个围墙把这些点围起来,距离最小是l
分析 :现在就是求凸包的周长然后再加上一个圆的周长
#include<stdio.h>
#include<string.h>
#include<stdlib.h>
#include<math.h>
#include<algorithm>
#include<iostream>
#include<queue> using namespace std;
#define N 1005
#define pi acos(-1.0)
#define ESP 1e-8 int s[N]; struct Point
{
double x,y;
Point(double x=,double y=):x(x),y(y){}
Point operator - (const Point &temp)const
{
return Point(x-temp.x,y-temp.y);
}
Point operator + (const Point &temp)const
{
return Point(x+temp.x,y+temp.y);
}
bool operator == (const Point &temp)const
{
return (x==temp.x && y==temp.y);
}
double operator * (const Point &temp)const
{
return (x*temp.x+y*temp.y);
}
int operator ^ (const Point &temp)const{
double t=x*temp.y-y*temp.x;
if(t>ESP)
return ;
if(fabs(t)<ESP)
return ;
return -;
}
}a[N]; double dist(Point a,Point b)
{
return sqrt((a-b)*(a-b));
} int cmp(Point a1,Point a2)
{
int t=((a1-a[])^(a2-a[]));
if(t==)
return dist(a1,a[])<dist(a2,a[]);
else
return t>;
}
int top;
void Graham(int n)///求凸包
{
s[]=;
s[]=;
top=;
for(int i=;i<n;i++)
{
while(top> && ((a[i]-a[s[top]])^(a[s[top-]]-a[s[top]]))<=)
top--;
s[++top]=i;
} } int main()
{
int n,l;
while(scanf("%d %d",&n,&l)!=EOF)
{
memset(s,,sizeof(s));
int k=;
for(int i=;i<n;i++)
{
scanf("%lf %lf",&a[i].x,&a[i].y);
if(a[i].y<a[k].y || (a[i].y==a[k].y && a[i].x<a[k].x))
k=i;
}
swap(a[],a[k]);
sort(a+,a+n,cmp); Graham(n);
double C=;
for(int i=;i<=top;i++)
{
C+=dist(a[s[i]],a[s[i-]]);
}
C+=dist(a[s[]],a[s[top]]);
C+=*pi*l;
printf("%.0lf\n",C);
}
return ;
}