HDU 1392 Surround the Trees

http://acm.hdu.edu.cn/showproblem.php?pid=1392

典型的凸包問題

#include <stdio.h>
#include <stdlib.h>
#include <math.h>
#define _DEBUG 1
#define MAX_TREE 110

typedef struct {
	double x,y;
}Point;
Point pts[MAX_TREE];
Point chs[MAX_TREE];
inline void exchange(Point &pa,Point &pb){
	Point tmp = pa;
	pa = pb;
	pb = tmp;
}

double dist(Point pa,Point pb){
	return sqrt((pa.x-pb.x)*(pa.x-pb.x)+(pa.y-pb.y)*(pa.y-pb.y));
}

double crossMultiple(Point p0,Point p1,Point p2){
	return (p1.x-p0.x)*(p2.y-p0.y)-(p2.x-p0.x)*(p1.y-p0.y);
}

int compare(const void *p1,const void *p2){
	Point p3 = *(Point *)p1;
	Point p4 = *(Point *)p2;

	double cm = crossMultiple(pts[0],p3,p4);
	if(cm < 0)
		return 1;
	else if(cm == 0 && dist(pts[0],p3) > dist(pts[0],p4))
		return 1;
	else
		return -1;
}


double convexHull(int n){
	int i;
	int tmp=0;
	double sum = 0;

	for(i=1;i<n;++i){//尋找第0個點
		if(pts[i].y < pts[tmp].y)
			tmp = i;
		else if(fabs(pts[i].y-pts[tmp].y)<0.000001){//不嚴格
			if(pts[i].x < pts[tmp].x)
				tmp=i;
		}		
	}
	exchange(pts[tmp],pts[0]);

	qsort(pts+1,n-1,sizeof(Point),compare);//排序,注意不包含第0個

	chs[0] = pts[0];
	chs[1] = pts[1];
	int top = 1;
	for(i=2;i<n;++i){
		while(top>=1 && crossMultiple(chs[top-1],chs[top],pts[i]) <= 0)
			top--;
		chs[++top] = pts[i];		 
	}	
	chs[++top] = chs[0];
	for(i=0;i<top;i++){
		sum += dist(chs[i],chs[i+1]); 		      
	}	
	return sum;
}
int main(){
	int n;
	int i;
#if _DEBUG==1
	freopen("hdu1392.in","r",stdin);
#endif
	while(scanf("%d",&n) && n!=0){
		for(i=0;i<n;++i){
			scanf("%lf %lf",&pts[i].x,&pts[i].y);
		}
		if(n==1){
			printf("%.2f\n",0.00);
			continue;
		}
		if(n==2){//注意兩個點的情況:n=2的時候,輸出那2個點的EuclidDis
			printf("%.2lf\n",dist(pts[0],pts[1]));
			continue;
		}

		double sum = convexHull(n);
		printf("%.2lf\n",sum);
	}
	return 0;
}


 

發表評論
所有評論
還沒有人評論,想成為第一個評論的人麼? 請在上方評論欄輸入並且點擊發布.
相關文章