poj 1113(凸包)

#include<stdio.h>
#include<math.h>
#include<stdlib.h>
#define INF 1e9
#define MAXV 1010
#define PI 3.1415926
int n;
struct Point
{
	double x,y;
}point[1010],tmp;

int findminpoint()
{
	double ymin=INF,xmin=INF;
	int i,v;
	for(i=0;i<n;i++)
		if(point[i].y<ymin)
		{
			v=i;
			ymin=point[i].y;
		}
		for(i=0;i<n;i++)
			if(point[i].y==ymin && point[i].x<xmin)
			{
				v=i;
				xmin=point[i].x;
			}
			return v;
}
double chaji(struct Point a1,struct Point b1,struct Point a2,struct Point b2)
{
	double x1=b1.x-a1.x;
	double y1=b1.y-a1.y;
	double x2=b2.x-a2.x;
    double y2=b2.y-a2.y;
    return x1*y2-x2*y1;
}
double distance(double x1,double y1,double x2,double y2)
{
	double dis=(x1-x2)*(x1-x2)+(y1-y2)*(y1-y2);
	return sqrt(dis);
}

int cmp(const void *p1,const void *p2)
{
	struct  Point *a=(struct  Point *)p1;
	struct  Point *b=(struct  Point *)p2;  //出现问题  改了很久
	double flag=chaji(point[0],*a,point[0],*b);
	if(flag>0) return -1;
	
    else if(!flag && distance((a->x),(a->y),point[0].x,point[0].y)<distance((b->x),(b->y),point[0].x,point[0].y)) 
        return -1; 
	return 1;
}



double graham(){ 
	int d[MAXV],dtop=0; 
	int i; 
	double l; 
	
				d[dtop++]=0; 
				d[dtop++]=1; 
				for(i=2;i<n;i++){ 
					while(chaji(point[d[dtop-2]],point[d[dtop-1]],point[d[dtop-1]],point[i])<0) dtop--; 
					d[dtop++]=i; 
				} 
				
				l=0; 
				for(i=1;i<dtop;i++) 
					l+=distance(point[d[i]].x,point[d[i]].y,point[d[i-1]].x,point[d[i-1]].y); 
				l+=distance(point[d[0]].x,point[d[0]].y,point[d[i-1]].x,point[d[i-1]].y); 
				//printf("%.2lf\n",l); 
				return l;
} 


double work()
{
	int h;
	h=findminpoint();
	tmp=point[0];
	point[0]=point[h];
	point[h]=tmp;  //居然这里出了问题 找了半天
	qsort(point+1,n-1,sizeof(point[0]),cmp);
	return graham();
	
}

int main()
{
	int l,i;
	double ans;
	while(scanf("%d%d",&n,&l)!=EOF)
	{
		for(i=0;i<n;i++)
			scanf("%lf%lf",&point[i].x,&point[i].y);
		ans=0;
		ans+=work();
		//printf("++++%lf+++\n",2*PI*l);
		ans+=2*PI*l;
		printf("%.lf\n",ans);
		
	}
	
	
	return 0;
}

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

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值