1. 程式人生 > >TZOJ--5112: Fencing the Cows(凸包)

TZOJ--5112: Fencing the Cows(凸包)

5112: Fencing the Cows 

時間限制(普通/Java):1000MS/3000MS     記憶體限制:65536KByte

描述

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.

輸入

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.

輸出

The output should consists of one real number, the length of fence required. The output should be accurate to two decimal places.

樣例輸入

4
4 8
4 12
5 9.3
7 8

樣例輸出

 12.00

題目來源

USACO

 

題目連結:http://tzcoder.cn/acmhome/problemdetail.do?&method=showdetail&id=5112

 

題目大意,求凸包的周長。

#include <bits/stdc++.h>
using namespace std;
struct Point{
    double x,y;
};
double dis(Point p1,Point p2)
{
    return sqrt((p1.x-p2.x)*(p1.x-p2.x)+(p1.y-p2.y)*(p1.y-p2.y));
}
double xmulti(Point p1,Point p2,Point p0) 
{
    return (p1.x-p0.x)*(p2.y-p0.y)-(p2.x-p0.x)*(p1.y-p0.y);
}
double graham(Point p[],int n)
{
    int pl[10005];
    int t = 1;
    for(int i=1;i<=n;i++)
        if(p[i].y < p[t].y)
            t = i;
    pl[1] = t;
    int num = 1;
    do{
        num++;
        t = pl[num-1]+1;
        if(t>n) t = 1;
        for(int i=1;i<=n;i++){
            double x = xmulti(p[i],p[t],p[pl[num-1]]);
            if(x<0) t = i;
        }
        pl[num] = t;
    } while(pl[num]!=pl[1]);
    double sum = 0;
    for(int i=1;i<num;i++)
        sum += dis(p[pl[i]],p[pl[i+1]]);
    return sum;
}
int main()
{
	Point a[11111];
	int n;
	while(cin>>n){
		for(int i=1;i<=n;i++)
		    scanf("%lf %lf",&a[i].x,&a[i].y);
		printf("%.2f\n",graham(a,n));
	}
	return 0;
}