Poj 1113 Wall (凸包Graham水平序)
以前做过的题,现在重新写下。
以前的解题报告:http://blog.csdn.net/whyorwhnt/article/details/8316442
#include <cmath>
#include <cstdio>
#include <cstring>
#include <algorithm>
using namespace std;
const double PI=acos(-1.0);
const double eps=1e-8;
const int N=1005;
struct Point //点,向量
{
double x,y;
Point(){}
Point(double _x,double _y)
{x=_x;y=_y;}
void Get ()
{scanf("%lf%lf",&x,&y);}
Point operator-(const Point &b)const
{return Point(x-b.x,y-b.y);}
Point operator+(const Point &b)
{return Point(x+b.x,y+b.y);}
Point operator*(const double k) //数乘
{return Point(x*k,y*k);}
double operator*(const Point a) //点乘
{return x*a.x+y*a.y;}
double operator^(const Point a) //叉乘
{return x*a.y-y*a.x;}
int DB (double dx) //判0函数
{
if(fabs(dx)<eps) return 0;
return dx>0?1:-1;
}
//调用点a的该函数
//返回1点a在向量bc的左侧
//返回-1点a在向量bc的右侧
//返回0点a在向量bc这条直线上
int Cross (Point b,Point c)
{return DB((b.x-x)*(c.y-y)-(c.x-x)*(b.y-y));}
bool operator < (const Point &b)const //用于排序
{
if (fabs(y-b.y)<eps) return x-b.x<0;
return y-b.y<0;
}
double Dis (Point ch)
{return sqrt((x-ch.x)*(x-ch.x)+(y-ch.y)*(y-ch.y));}
}pt[N],ch[N];
int n,len;
//求凸包函数
//pt:所有的点,n个,pt[0]到pt[n-1]
//ch:求完的凸包中的点,len个,q[0]到q[len-1]
void Graham (Point pt[],Point ch[],int &len,int n) //只保存凸包顶点
{
int i,top=1;
sort(pt,pt+n);
ch[0]=pt[0];
ch[1]=pt[1];
for (i=2;i<n;i++)
{
while (top>0 && ch[top-1].Cross(ch[top],pt[i]) <= 0)
top--;
ch[++top]=pt[i];
}
int temp=top;
for (i=n-2;i>=0;i--)
{
while (top>temp && ch[top-1].Cross(ch[top],pt[i]) <= 0)
top--;
ch[++top]=pt[i];
}
len=top;
}
int main ()
{
int L,i,n,len;
double ans=0;
scanf("%d%d",&n,&L);
for (i=0;i<n;i++)
pt[i].Get();
Graham (pt,ch,len,n);
for (i=0;i<len;i++)
ans+=ch[i].Dis(ch[(i+1)%len]);
ans+=PI*2*L;
printf("%.0lf\n",ans);
return 0;
}
还没有评论,来说两句吧...