USACO 5.1 Fencing the Cows

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

————————————————————————————————题解

一道凸包求周长的题,卷包裹算法,如果栈中的后两个点组成的向量和新加入的点和最后点的向量是顺时针旋转,那么就不符合凸包的性质,弹出直到符合性质即可

  1 /*
  2 ID: ivorysi
  3 LANG: C++
  4 TASK: fc
  5 */
  6 #include <iostream>
  7 #include <cstdio>
  8 #include <cstring>
  9 #include <algorithm>
 10 #include <queue>
 11 #include <set>
 12 #include <vector>
 13 #include <string.h>
 14 #include <cmath>
 15 #define siji(i,x,y) for(int i=(x);i<=(y);++i)
 16 #define gongzi(j,x,y) for(int j=(x);j>=(y);--j)
 17 #define xiaosiji(i,x,y) for(int i=(x);i<(y);++i)
 18 #define sigongzi(j,x,y) for(int j=(x);j>(y);--j)
 19 #define inf 0x7fffffff
 20 #define ivorysi
 21 #define mo 97797977
 22 #define hash 974711
 23 #define base 47
 24 #define pss pair<string,string>
 25 #define MAXN 5000
 26 #define fi first
 27 #define se second
 28 #define pii pair<int,int>
 29 #define esp 1e-8
 30 typedef long long ll;
 31 using namespace std;
 32 struct vec {
 33     double x,y;
 34     vec(double x=0.0,double y=0.0) :x(x),y(y) {}
 35     vec operator - (const vec &b) const{
 36         return vec(x-b.x,y-b.y);
 37     }
 38     double norm() const{
 39         return x*x+y*y;
 40     }
 41 }a[10005];
 42 int n;
 43 bool dcmp(double a,double b=0.0) {
 44     return fabs(a-b) < esp ? 1 :0 ;
 45 }
 46 double cross(vec a,vec b) {
 47     return  a.x*b.y-a.y*b.x; 
 48 }
 49 inline bool cmp(const vec &c,const vec &d) {
 50     vec t1= c-a[1],t2=d-a[1];
 51     double t=cross(t1,t2);
 52     if(!dcmp(t)) return t>0;//逆时针为正,顺时针为负
 53     else return c.norm()<d.norm(); 
 54 }
 55 double o(double a){
 56     return a*a;
 57 }
 58 struct poly {
 59     vector<vec> poi;
 60     double peri() {
 61         double res=0.0;
 62         siji(i,1,poi.size()-1) {
 63             res+=sqrt(o(poi[i].x-poi[i-1].x)+o(poi[i].y-poi[i-1].y));
 64         }
 65         res+=sqrt(o(poi[0].x-poi[poi.size()-1].x)+o(poi[0].y-poi[poi.size()-1].y));
 66         return res;
 67     }
 68     void convex() {
 69         int id=1;
 70         siji(i,2,n) {
 71             if(a[i].x<a[id].x || (a[i].x==a[id].x && a[i].y<a[id].y)) {
 72                 id=i;
 73             }
 74         }
 75         if(id!=1) swap(a[id],a[1]);
 76         sort(a+2,a+1+n,&cmp);
 77         poi.push_back(a[1]);
 78         siji(i,2,n) {
 79             while(poi.size() >=2 && 
 80                 cross(poi[poi.size()-1]-poi[poi.size()-2],a[i]-poi[poi.size()-1])<=0) 
 81                 poi.pop_back();
 82             poi.push_back(a[i]);
 83         }
 84     }
 85 }tw;
 86 
 87 void solve() {
 88     scanf("%d",&n);
 89     siji(i,1,n) {
 90         scanf("%lf%lf",&a[i].x,&a[i].y);
 91     }
 92     tw.convex();
 93     printf("%.2lf\n",tw.peri());
 94 } 
 95 int main(int argc, char const *argv[])
 96 {
 97 #ifdef ivorysi
 98     freopen("fc.in","r",stdin);
 99     freopen("fc.out","w",stdout);
100 #else
101     freopen("f1.in","r",stdin);
102 #endif
103     solve();
104     return 0;
105 }

 

转载于:https://www.cnblogs.com/ivorysi/p/6379868.html

  • 0
    点赞
  • 0
    收藏
    觉得还不错? 一键收藏
  • 0
    评论
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值