现在的位置: 首页 > 综合 > 正文

usaco 5.1 Fencing the Cows(凸包模板题)

2013年10月31日 ⁄ 综合 ⁄ 共 1926字 ⁄ 字号 评论关闭

Fencing the Cows
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: 15114582
PROG: fc
LANG: C++
*/
#include<cmath>
#include<cstdio>
#include<iostream>
#include<algorithm>
using namespace std;
const int mm=11111;
typedef double diy;
struct point
{
    diy x,y;
    point(){}
    point(diy _x,diy _y):x(_x),y(_y){}
}g[mm],q[mm];
point Vector(point s,point t)
{
    return point(t.x-s.x,t.y-s.y);
}
diy CrossProduct(point P,point Q)
{
    return P.x*Q.y-P.y*Q.x;
}
diy MultiCross(point P,point Q,point R)
{
    return CrossProduct(Vector(Q,P),Vector(Q,R));
}
diy SqrDis(point P,point Q)
{
    return (P.x-Q.x)*(P.x-Q.x)+(P.y-Q.y)*(P.y-Q.y);
}
bool TurnRight(point P,point Q,point R)
{
    diy tmp=MultiCross(P,Q,R);
    if(tmp>0)return 1;
    if(tmp<0)return 0;
    return SqrDis(P,Q)<SqrDis(P,R);
}
bool cmp(point P,point Q)
{
    return TurnRight(g[0],Q,P);
}
void Graham(int n,int &m)
{
    int i,j;
    for(j=i=0;i<n;++i)
        if(g[i].x<g[j].x||(g[i].x==g[j].x&&g[i].y<g[j].y))j=i;
    swap(g[0],g[j]);
    sort(g+1,g+n,cmp);
    q[m=0]=g[n]=g[0];
    for(i=1;i<=n;++i)
    {
        while(m&&TurnRight(q[m-1],q[m],g[i]))--m;
        q[++m]=g[i];
    }
}
int main()
{
    freopen("fc.in","r",stdin);
    freopen("fc.out","w",stdout);
    int i,n,m;
    diy ans;
    while(~scanf("%d",&n))
    {
        for(i=0;i<n;++i)
            scanf("%lf%lf",&g[i].x,&g[i].y);
        Graham(n,m);
        for(ans=i=0;i<m;++i)
            ans+=sqrt(SqrDis(q[i],q[i+1]));
        printf("%.2lf\n",ans);
    }
    return 0;
}

抱歉!评论已关闭.