hdoj1392

Problem : 1392 ( Surround the Trees )     Judge Status : Accepted
RunId : 2853191    Language : C++    Author : huwenbiao
Code Render Status : Rendered By HDOJ C++ Code Render Version 0.01 Beta
/***************************************************************\
*Author:Hu Wenbiao
*Created Time: Sat 21 Aug 2010 10:33:05 AM CST
*File Name: main.cpp
*Description:几何题目。凸包问题。Graham's scan处理
\***************************************************************/

//*========================*Head File*========================*\\

#include<iostream>
#include<stdio.h>
#include<stdlib.h>
#include<string.h>
#include<math.h>
/*----------------------*Global Variable*----------------------*/
struct
POINT{
int
x,y;
}
P[
40000];
int
Q[
40000];
int
top,n;

//*=======================*Main Program*=======================*//
using namespace std;

int
cmp(const void* i,const void* j){
//如果0->i->j是左转,则i在前
POINT *a=(POINT*)i,*b=(POINT*)j;
int
tmp=(a->x-P[
0].x)*(b->y-P[0].y)-(a->y-P[0].y)*(b->x-P[0].x);
if
(tmp>
0)
return
-
1;
else if
(tmp<
0)
return
1;
else
{
//如果0->i->j在一条直线上,到0距离小的在前,其实只当出现了
//排好序后0->1->2在一条直线上这种情况,这个讨论才是必要的,
//这种情况其实本题数据中没有出现。
int dx=a->x-P[0].x,dy=a->y-P[0].y;
int
da=dx*dx+dy*dy;
dx=b->x-P[
0].x,dy=b->y-P[0].y;
int
db=dx*dx+dy*dy;
return
da-db;
}
}

int
cross(int a,int b,int c){
//返回(P[a],P[b]),(P[a],P[c])的叉积
int x1=P[b].x-P[a].x,y1=P[b].y-P[a].y;
int
x2=P[c].x-P[a].x,y2=P[c].y-P[a].y;
return
x1*y2-y1*x2;
}

int
main(){

//freopen("input","r",stdin);
while(scanf("%d",&n)!=EOF&&n){
int
_min=
0;//P[_min]是最下方的点,如果有y相同的情况,取最左边的点
for(int i=0;i<n;i++){
scanf(
"%d%d",&P[i].x,&P[i].y);
if
(P[i].y<P[_min].y)
_min=i;
else if
(P[i].y==P[_min].y&&P[i].x<P[_min].x)
_min=i;
}

if
(n==
1){
printf(
"0.00\n");
continue
;
}

else if
(n==
2){
printf(
"%.2lf\n",sqrt(1.0*(P[0].x-P[1].x)*(P[0].x-P[1].x)+(P[0].y-P[1].y)*(P[0].y-P[1].y)));
continue
;
}

swap(P[
0],P[_min]);
qsort(&P[
1],n-1,sizeof(POINT),cmp);
top=
0;
Q[top++]=
0;
Q[top++]=
1;
for
(int i=
2;i<n;i++){
while
(cross(Q[top-
2],Q[top-1],i)<=0)//右转或在一条直线上
top--;
Q[top++]=i;
}

//别忘了这种情况
double ans=sqrt(1.0*(P[Q[top-1]].x-P[Q[0]].x)*(P[Q[top-1]].x-P[Q[0]].x)+(P[Q[top-1]].y-P[Q[0]].y)*(P[Q[top-1]].y-P[Q[0]].y));
for
(int i=
1;i<top;i++){
ans+=sqrt(
1.0*(P[Q[i]].x-P[Q[i-1]].x)*(P[Q[i]].x-P[Q[i-1]].x)+(P[Q[i]].y-P[Q[i-1]].y)*(P[Q[i]].y-P[Q[i-1]].y));
}

printf(
"%.2lf\n",ans);
}
}
posted @ 2010-08-21 16:37  open source  阅读(180)  评论(0编辑  收藏  举报