Hal Burch
Farmer John wishes to build a fence to contain his cows, but he's a bit short on cash right. Any fence he builds must contain all of the favorite grazing spots for his cows. Given the location of these spots, determine the length of the shortest fence which encloses them.
PROGRAM NAME: fc
INPUT FORMAT
The first line of the input file contains one integer, N. N (0 <= N <= 10,000) is the number of grazing spots that Farmer john wishes to enclose. The next N line consists of two real numbers, Xi and Yi, corresponding to the location of the grazing spots in the plane (-1,000,000 <= Xi,Yi <= 1,000,000). The numbers will be in decimal format.
SAMPLE INPUT (file fc.in)
4 4 8 4 12 5 9.3 7 8
OUTPUT FORMAT
The output should consists of one real number, the length of fence required. The output should be accurate to two decimal places.
SAMPLE OUTPUT (file fc.out)
12.00
/*
ID: conicoc1
LANG: C
TASK: fc
*/
#include<stdio.h>
#include<string.h>
#include<stdlib.h>
#include<math.h>
#define INIFINITY 1000001
#define eps 0.000001
typedef struct Point
{
double x;
double y;
}Point;
Point Pt[10000];
int Count;
int Stack[10001];
int Top=0;
double DistSum;
int MinPt;
double Multiply(Point sp,Point ep,Point op)
{
return (sp.x-op.x)*(ep.y-op.y)-(sp.y-op.y)*(ep.x-op.x);
/*返回值>0,sp在opep的顺时针方向。<0,sp在opep的逆时针方向。=0共线,可能同向也可能逆向*/
}
double Dist(Point a,Point b)
{
return sqrt((a.x-b.x)*(a.x-b.x)+(a.y-b.y)*(a.y-b.y));
}
int comp1(const void *a,const void *b)
{
Point *p1=(Point*)a;
Point *p2=(Point*)b;
if(p1->y==p2->y)
return p1->x-p2->x;
return p1->y-p2->y;
}
double Polar(Point *p)
{
return atan2(p->y-Pt[0].y,p->x-Pt[0].x);
}
int comp2(const void *a,const void *b)
{
Point *p1=(Point *)a;
Point *p2=(Point *)b;
return Polar(p1)>Polar(p2);
}
void Graham()
{
int i;
Stack[0]=0;
Stack[1]=1;
Stack[2]=2;
Top=3;
for(i=3;i<Count;i++){
while(Multiply(Pt[i],Pt[Stack[Top-1]],Pt[Stack[Top-2]])>=0)
Top--;
Stack[Top++]=i;
}
}
int main()
{
int i;
FILE *fin,*fout;
fin=fopen("fc.in","r");
fout=fopen("fc.out","w");
fscanf(fin,"%d",&Count);
for(i=0;i<Count;i++)
fscanf(fin,"%lf %lf",&Pt[i].x,&Pt[i].y);
qsort(Pt,Count,sizeof(Point),comp1);
qsort(Pt+1,Count-1,sizeof(Point),comp2);
Graham();
DistSum=Dist(Pt[Stack[Top-1]],Pt[Stack[0]]);
for(i=0;i<Top-1;i++)
DistSum+=Dist(Pt[Stack[i]],Pt[Stack[i+1]]);
fprintf(fout,"%.2lf\n",DistSum);
return 0;
}
计算几何里一道裸的凸包。。Graham算法用栈计算凸包,学习了!