hdu1392 Surround the Trees 凸包

第一次做凸包,这道题要特殊考虑下,n=2时的情况,要除以二才行。

我是从最左边的点出发,每次取斜率最大的点,一直到最右边的点。

然后从最左边的点出发,每次取斜率最低的点,一直到最右边的点。

#include<stdio.h>

#include<math.h>

#include<algorithm>

#include<string.h>

using namespace std;

const double eps=1e-9;

struct node

{

	double x,y;

}f[105];

bool flag[105];

int n;

bool cmp(node a,node b)

{

	return fabs(a.x-b.x)<eps?(a.y<b.y):(a.x<b.x);

}

double xielv(int a,int b)//求斜率

{

	return (f[a].y-f[b].y)/(f[a].x-f[b].x);

}

double dis(int a,int b)//求距离

{

	double xx=f[a].x-f[b].x,yy=f[a].y-f[b].y;

	return sqrt(xx*xx+yy*yy);

}

void calans()//计算最短周长

{

	int i,j,now=0,maxi;

	double ans=0;

	while(1)

	{

		double max=-4000000;//斜率最大值

		maxi=now;

		for(i=1;i<n;i++)

		{

			if(flag[i])continue;

			if(-f[i].x+f[now].x>eps)continue;//在当前点的左边,不考虑

			if(fabs(f[now].x-f[i].x)<eps)

			{

				if(f[now].y>f[i].y)//在当前点的正下方,不考虑

				  continue;

		        maxi=i;

		        break;

			}

			else

			{

				double p=xielv(now,i);

				if(p>max)

	            {

	            	maxi=i;

	            	max=p;

	            }

			}

		}

		flag[maxi]=1;

		ans+=dis(now,maxi);

		if(maxi==now)

		{

		  flag[maxi]=0;//最后右边的点要计算两次,去除标记

		  break;

		}

		now=maxi;

	}

	now=0;

	while(1)//每次取斜率最小的点

	{

		double min=4000000;

		int mini=now;

		for(i=1;i<n;i++)

		{

			if(flag[i])continue;

			if(-f[i].x+f[now].x>eps)continue;//在当前点的左边,不考虑



			if(fabs(f[i].x-f[now].x)<eps)

			{

				if(f[i].x+0.1<f[n-1].x)//在当前点的正下方,不考虑



				   continue;

                mini=i;

                break;

			}

				double p=xielv(now,i);

				if(p<min)

	            {

	            	mini=i;

	            	min=p;

	            }

		}

		ans+=dis(now,mini);

		flag[mini]=1;

	    if(mini==now)

	       break;

		now=mini;

	}

	if(n==2)ans/=2;//n=2时,除以二

	printf("%.2f\n",ans);

}

int main()

{

	int i,j;

	while(scanf("%d",&n)!=-1&&n)

	{

		memset(flag,0,sizeof(flag));

		for(i=0;i<n;i++)

		  scanf("%lf%lf",&f[i].x,&f[i].y);

        sort(f,f+n,cmp);

	    calans();

	}

	return 0;

}


你可能感兴趣的:(round)