您的位置:首页 > Web前端

USACO 5.1.1 Fencing the Cows 圈奶牛 题解与分析

2013-12-19 22:04 417 查看
Fencing the Cows圈奶牛

译 by Felicia Crazy

目录

 [隐藏
1
描述
2
格式
3
SAMPLE INPUT (file fc.in)
4
SAMPLE OUTPUT (file fc.out)

描述

农夫约翰想要建造一个围栏用来围住他的奶牛,可是他资金匮乏。他建造的围栏必须包括他的奶牛喜欢吃草的所有地点。对于给出的这些地点的坐标,计算最短的能够围住这些点的围栏的长度。

格式

PROGRAM NAME: fc

INPUT FORMAT

输入数据的第一行包括一个整数 N。N(0 <= N <= 10,000)表示农夫约翰想要围住的放牧点的数目。接下来 N 行,每行由两个实数组成,Xi 和 Yi,对应平面上的放牧点坐标(-1,000,000 <= Xi,Yi <= 1,000,000)。数字用小数表示。

OUTPUT FORMAT

输出必须包括一个实数,表示必须的围栏的长度。答案保留两位小数。

SAMPLE INPUT (file fc.in)

4
4 8
4 12
5 9.3
7 8


SAMPLE OUTPUT (file fc.out)

12.00

【分析】:

求二维凸包,计算几何问题可以参见:计算几何之基础知识及例题  , [u]计算几何之题目讲解 [/u]

 

【代码】:

/*
ID:csyzcyj1
PROG:fc
LANG:C++
*/
#include<stdio.h>
#include<string.h>
#include<stdlib.h>
#include<algorithm>
#include<iostream>
#include<cmath>
using namespace std;
#define MAXN 20001
struct point{double x,y;};
point a[MAXN];
int N,stack[MAXN],top;
double ans=0.0;
double dist(double x1,double y1,double x2,double y2){return sqrt((x1-x2)*(x1-x2)+(y1-y2)*(y1-y2));}
bool cmp(point X,point Y)
{
double x1=X.x,y1=X.y,x2=Y.x,y2=Y.y;
if(x1*y2-x2*y1==0.0)
return x1<x2;
return ((x1*y2-x2*y1)>0.0);
}
void prepare()
{
int basic=1;
for(int i=2;i<=N;i++)
if(a[i].x<a[basic].x || (a[i].x==a[basic].x && a[i].y<a[basic].y))
basic=i;
swap(a[1],a[basic]);
for(int i=2;i<=N;i++)
a[i].x-=a[1].x,a[i].y-=a[1].y;
a[1].x=0.0,a[1].y=0.0;
sort(a+2,a+1+N,cmp);
a[N+1].x=0.0,a[N+1].y=0.0;
}
void Convexhull()
{
int now1,now2;
double x1,x2,y1,y2;
top=3;
stack[1]=1,stack[2]=2,stack[3]=3;
for(int i=4;i<=N+1;i++)
{
now1=stack[top-1],now2=stack[top];
x1=a[now2].x-a[now1].x;
y1=a[now2].y-a[now1].y;
x2=a[i].x-a[now2].x;
y2=a[i].y-a[now2].y;
while((x1*y2-x2*y1)<0.0)
{
top--;
now1=stack[top-1],now2=stack[top];
x1=a[now2].x-a[now1].x;
y1=a[now2].y-a[now1].y;
x2=a[i].x-a[now2].x;
y2=a[i].y-a[now2].y;
}
stack[++top]=i;
}
}
void figure()
{
for(int i=top;i>=2;i--)
ans+=dist(a[stack[i]].x,a[stack[i]].y,a[stack[i-1]].x,a[stack[i-1]].y);
}
int main()
{
freopen("fc.in","r",stdin);
freopen("fc.out","w",stdout);
scanf("%d",&N);
for(int i=1;i<=N;i++)
scanf("%lf%lf",&a[i].x,&a[i].y);
prepare();
Convexhull();
figure();
printf("%.2lf\n",ans);
//system("pause");
return 0;
}


 

测评信息:

TASK: fc
LANG: C++

Compiling...
Compile: OK

Executing...
Test 1: TEST OK [0.000 secs, 3772 KB]
Test 2: TEST OK [0.000 secs, 3772 KB]
Test 3: TEST OK [0.011 secs, 3772 KB]
Test 4: TEST OK [0.011 secs, 3772 KB]
Test 5: TEST OK [0.011 secs, 3772 KB]
Test 6: TEST OK [0.011 secs, 3772 KB]
Test 7: TEST OK [0.022 secs, 3772 KB]
Test 8: TEST OK [0.065 secs, 3772 KB]

All tests OK.
YOUR PROGRAM ('fc') WORKED FIRST TIME!  That's fantastic
-- and a rare thing.  Please accept these special automated
congratulations.


转载注明出处:http://blog.csdn.net/u011400953
内容来自用户分享和网络整理,不保证内容的准确性,如有侵权内容,可联系管理员处理 点击这里给我发消息
标签: