- 圈奶牛
★★☆ 输入文件:fc.in 输出文件:fc.out 简单对比
时间限制:1 s 内存限制:128 MB
USACO/fc(译by Felicia Crazy)
描述
农夫约翰想要建造一个围栏用来围住他的奶牛,可是他资金匮乏。他建造的围栏必须包括他的奶牛喜欢吃草的所有地点。对于给出的这些地点的坐标,计算最短的能够围住这些点的围栏的长度。
PROGRAM NAME: fc
INPUT FORMAT(file fc.in)
输入数据的第一行包括一个整数 N。N(0 <= N <= 10,000)表示农夫约翰想要围住的放牧点的数目。接下来 N 行,每行由两个实数组成,Xi 和 Yi,对应平面上的放牧点坐标(-1,000,000 <= Xi,Yi <= 1,000,000)。数字用小数表示。
OUTPUT FORMAT(file fc.out)
输出必须包括一个实数,表示必须的围栏的长度。答案保留两位小数。
SAMPLE INPUT (file fc.in)
4
4 8
4 12
5 9.3
7 8
SAMPLE OUTPUT (file fc.out)
12.00
裸凸包。。
要进攻计算几何了233
是一个值得庆祝的日子。。
附上本蒟蒻的代码:
#include<cstdio>
#include<iostream>
#include<cmath>
#include<algorithm>
using namespace std;
int n,top;
double ans;
struct node
{
double x,y;
};
node p[10001],s[10001];
double dis(const node a,const node b)
{
return sqrt((a.x-b.x)*(a.x-b.x)+(a.y-b.y)*(a.y-b.y));
}
double mul(const node a,const node b,const node p0)
{
return (a.x-p0.x)*(b.y-p0.y)-(b.x-p0.x)*(a.y-p0.y);
}
bool cmp(const node a,const node b)
{
if (mul(a,b,p[0])==0)
return dis(a,p[0])<dis(b,p[0]);
return mul(a,b,p[0])>0;
}
void graham()
{
int k=0,i;
node t;
top=2;
for (i=1;i<n;i++)
if ((p[k].y>p[i].y) || (p[k].y==p[i].y && p[k].x>p[i].x))
k=i;
t=p[0];
p[0]=p[k];
p[k]=t;
sort(p+1,p+n,cmp);
s[0]=p[0];
s[1]=p[1];
s[2]=p[2];
for (i=3;i<n;i++)
{
while (top && mul(p[i],s[top],s[top-1])>=0)
top--;
top++;
s[top]=p[i];
}
top++;
s[top]=p[0];
for (i=0;i<top;i++)
ans+=dis(s[i],s[i+1]);
}
int main()
{
freopen("fc.in","r",stdin);
freopen("fc.out","w",stdout);
int i;
scanf("%d",&n);
for (i=0;i<n;i++)
scanf("%lf%lf",&p[i].x,&p[i].y);
graham();
printf("%.2lf",ans);
fclose(stdin);
fclose(stdout);
return 0;
}