hdu 1392 凸包问题

10 篇文章 0 订阅

  凸包算法来自于:http://blog.csdn.net/fivedoumi/article/details/7653128

当  n==2 的时候要特殊考虑;

#include<stdio.h>
#include<stdlib.h>
#include<math.h>
#define maxn 1000
typedef struct point
{
	double x,y;
}point;

point set[maxn];
point ch[maxn];
int n,len;
double mul(point p1,point p2,point p0)
{
	return((p1.x-p0.x)*(p2.y-p0.y)-(p2.x-p0.x)*(p1.y-p0.y));
}

double dis(point p1,point p2)
{
	return(sqrt((p1.x-p2.x)*(p1.x-p2.x)+(p1.y-p2.y)*(p1.y-p2.y)));
}

void scan(point set[],point ch[],int n)
{
	int i,j,k=0,top=2;
	point tmp;

	for(i=1;i<n;i++)
		if((set[i].y<set[k].y)||((set[i].y==set[k].y)&&(set[i].x<set[k].x)))
			k=i;

	tmp=set[0];
	set[0]=set[k];
	set[k]=tmp;

	for(i=1;i<n-1;i++)
	{
		k=i;
		for(j=i+1;j<n;j++)
			if((mul(set[j],set[k],set[0])>0)
				||((mul(set[j],set[k],set[0])==0)
				&&(dis(set[0],set[j])<dis(set[0],set[k]))))
				k=j;
		tmp=set[i];
		set[i]=set[k];
		set[k]=tmp;
	}
	ch[0]=set[0];
	ch[1]=set[1];
	ch[2]=set[2];

	for(i=3;i<n;i++)
	{
		while(mul(set[i],ch[top],ch[top-1])>=0)top--;
		ch[++top]=set[i];
	}
	len=top+1;
}
int main()
{
	int i;
	double rope;
mark:while(scanf("%d",&n)&&n)
	{
		for(i=0;i<n;i++)
		{
			scanf("%lf%lf",&set[i].x,&set[i].y);
		}
		if(n==2)
		{
			printf("%.2lf\n",sqrt(((set[0].x-set[1].x)*(set[0].x-set[1].x))+((set[0].y-set[1].y)*(set[0].y-set[1].y))));
			goto mark;
		}
		scan(set,ch,n);
		rope = 0;
		for(i=0;i<len-1;i++)
		{
			rope+=sqrt((ch[i+1].x-ch[i].x)*(ch[i+1].x-ch[i].x)+(ch[i+1].y-ch[i].y)*(ch[i+1].y-ch[i].y));
		}
		rope += sqrt((ch[0].x-ch[len-1].x)*(ch[0].x-ch[len-1].x)+(ch[0].y-ch[len-1].y)*(ch[0].y-ch[len-1].y));
		printf("%.2lf\n",rope);
	}
	return 0;
}



  • 0
    点赞
  • 0
    收藏
    觉得还不错? 一键收藏
  • 0
    评论

“相关推荐”对你有帮助么?

  • 非常没帮助
  • 没帮助
  • 一般
  • 有帮助
  • 非常有帮助
提交
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值