1. 程式人生 > >[USACO5.1]圈奶牛Fencing the Cows

[USACO5.1]圈奶牛Fencing the Cows

cstring 想要 sort one n) dba add 1.0 freopen

題目描述

農夫約翰想要建造一個圍欄用來圍住他的奶牛,可是他資金匱乏。他建造的圍欄必須包括他的奶牛喜歡吃草的所有地點。對於給出的這些地點的坐標,計算最短的能夠圍住這些點的圍欄的長度。

輸入輸出格式

輸入格式:

輸入數據的第一行包括一個整數 N。N(0 <= N <= 10,000)表示農夫約翰想要圍住的放牧點的數目。接下來 N 行,每行由兩個實數組成,Xi 和 Yi,對應平面上的放牧點坐標(-1,000,000 <= Xi,Yi <= 1,000,000)。數字用小數表示。

輸出格式:

輸出必須包括一個實數,表示必須的圍欄的長度。答案保留兩位小數。

輸入輸出樣例

輸入樣例#1:
4
4 8
4 12
5 9.3
7 8
輸出樣例#1:
12.00

說明

題目翻譯來自NOCOW。

USACO Training Section 5.1

凸包模板題

坑點,一定要註意int 和double,debug一個晚上+早讀

NOF:一定要註意細節

技術分享圖片
 1 #include<iostream>
 2 #include<cstdio>
 3 #include<cstring>
 4 #include<algorithm>
 5 #include<cmath>
 6 #define PI 3.1415926535
 7 #define DB double
 8
#define eps 1e-8 9 using namespace std; 10 const int N=12000; 11 int T,n,L; 12 struct node{ 13 DB x,y; 14 }d[N],s[N]; 15 bool cmp1(node a,node b) 16 { 17 if(a.y!=b.y) return a.y<b.y; 18 else return a.x<b.x; 19 } 20 DB Cross(node a1,node a2,node b1,node b2) 21 { 22 return (a2.x-a1.x)*(b2.y-b1.y)-(b2.x-b1.x)*(a2.y-a1.y);
23 } 24 DB dis(node a,node b) 25 { 26 return sqrt((a.x-b.x)*(a.x-b.x)*1.0+(a.y-b.y)*(a.y-b.y)); 27 } 28 bool cmp2(node a,node b) 29 { 30 DB m=Cross(d[1],a,d[1],b); 31 if(m>0) return 1; 32 else if(m==0) return dis(d[0],a)<dis(d[0],b); 33 return 0; 34 } 35 int top; 36 DB ans; 37 int main() 38 { 39 freopen("fc.in","r",stdin); 40 freopen("fc.out","w",stdout); 41 scanf("%d",&n); 42 for(int i=1;i<=n;++i)scanf("%lf%lf",&d[i].x,&d[i].y); 43 sort(d+1,d+n+1,cmp1); 44 s[++top]=d[1]; 45 sort(d+2,d+n+1,cmp2); 46 s[++top]=d[2]; 47 for(int i=3;i<=n;++i) 48 { 49 while(top>=2 && Cross(s[top-1],s[top],s[top],d[i])<=0) top--; 50 s[++top]=d[i]; 51 } 52 for(int i=1;i<top;++i)ans+=dis(s[i],s[i+1]); 53 ans+=dis(s[1],s[top]); 54 printf("%.2lf\n",ans); 55 return 0; 56 }
View Code

君子之心事,天青日白,不可使人不知;君子之才華,玉韞珠藏,不可使人易知

[USACO5.1]圈奶牛Fencing the Cows