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;
}

  

转载于:https://www.cnblogs.com/Anidlebrain/p/10032321.html

评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值