分析:
给出N个点,求距离这N个点围成的多边形距离为L的围墙的周长。可以得出,这个周长就是多边形周长加上一个圆的周长。多半形周长可以先求出凸包点集,然后依次累加距离即可。然后这个题需要注意输出格式!最后一个输出数据不用加两个换行!!!题解:
1.求凸包:
int cmp(point a, point b) //水平排序
{
if(a.x==b.x)return a.y<b.y;
return a.x<b.x;
}
int convex(int n, point P[], point res[])//n为总点数,P 为点集,res为输出凸包上点的点集
{
sort(P, P+n,cmp);
int m=0,i,j,k;
//求得下凸包,逆时针
//已知凸包点m个,如果新加入点为i,则向量(m-2,i)必定要在(m-2,m-1)的逆时针方向才符合凸包的性质
//若不成立,则m-1点不在凸包上。
for(i=0;i<n;i++)
{
while(m>1&&multiply(res[m-1], P[i], res[m-2])<=0)
m--;
res[m++]=P[i];
}
k=m;
//求得上凸包
for(i=n-2;i>=0;i--)
{
while(m>k&&multiply(res[m-1],P[i],res[m-2])<=0)m--;
res[m++]=P[i];
}
if(n>1) m--;//起始点重复。
return m;
}
- AC代码:
#include <cstdio>
#include <cstring>
#include <cmath>
#include <iostream>
#include <algorithm>
using namespace std;
const double PI = 3.14159265;
int N, L;
struct point
{
double x;
double y;
}P[1234],res[1234];
int cmp(point a, point b) //水平排序
{
if(a.x==b.x)return a.y<b.y;
return a.x<b.x;
}
double multiply(point a, point b,point c)//向量积
{
return (a.x-c.x)*(b.y-c.y)-(b.x-c.x)*(a.y-c.y);
}
int convex(int n, point P[], point res[])//n为总点数,P 为点集,res为输出凸包上点的点集
{
sort(P, P+n,cmp);
int m=0,i,j,k;
//求得下凸包,逆时针
//已知凸包点m个,如果新加入点为i,则向量(m-2,i)必定要在(m-2,m-1)的逆时针方向才符合凸包的性质
//若不成立,则m-1点不在凸包上。
for(i=0;i<n;i++)
{
while(m>1&&multiply(res[m-1], P[i], res[m-2])<=0)
m--;
res[m++]=P[i];
}
k=m;
//求得上凸包
for(i=n-2;i>=0;i--)
{
while(m>k&&multiply(res[m-1],P[i],res[m-2])<=0)m--;
res[m++]=P[i];
}
if(n>1) m--;//起始点重复。
return m;
}
double dist(point p1,point p2) // 返回两点之间欧氏距离
{
return sqrt( (p1.x-p2.x)*(p1.x-p2.x)+(p1.y-p2.y)*(p1.y-p2.y) ) ;
}
int main()
{
int T;
scanf("%d", &T);
while(T--)
{
scanf("%d%d", &N, &L);
int t = 0;
while(t<N)
{
scanf("%lf%lf", &P[t].x, &P[t].y);
t++;
}
int len = convex(N, P, res);
double Length = PI * L * 2;
for(int i=0;i<len-1;i++)
{
Length += dist(res[i], res[i+1]);
}
Length += dist(res[len-1], res[0]);
printf("%.0lf\n", Length); //printf自带四舍五入
if(T) cout << endl;
}
return 0;
}