1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19 20 21 22 23 24 25 26 27 28 29 30 31 32 33 34 35 36 37 38 39 40 41 42 43 44 45 46 47 48 49 50 51 52 53 54 55 56 57 58 59 60 61 62 63 64 65 66 67 68 69 70 71 72 73 74 75 76 77 78 79 80 81 82 83 84 85 86 87 88 89 90 91
| #include<bits/stdc++.h> using namespace std; const double eps = 1e-8; int sign(double x) { if (fabs(x) < eps) return 0; if (x < 0) return -1; return 1; } struct Point{ double x, y; Point(double x = 0, double y = 0) : x(x), y(y) { } Point operator +(Point B){return Point(x+B.x,y+B.y);} Point operator -(Point B){return Point(x-B.x,y-B.y);} Point operator *(double k){return Point(x*k,y*k);} Point operator /(double k){return Point(x/k,y/k);} bool operator == (Point B){return sign(x-B.x)==0&&sign(y-B.x)==0;} bool operator <(Point B) {return sign(x-B.x)<0||sign(x-B.x)==0&&sign(y-B.y)<0;}
}; double cross(Point a, Point b){
return a.x * b.y - b.x * a.y; } double area(Point a, Point b, Point c){
return cross(b-a, c-a); } double get_len(Point a,Point b){ Point A=a-b; double W=A.x*A.x+A.y*A.y; W=sqrt(W); return W; } const int N=1e5+10; Point a[N]; int n,stk[N]; bool used[N]; vector<int>convex; double andrew(){ sort(a+1,a+1+n); int top=0; for(int i=1;i<=n;i++){ while(top>=2){ double B=area(a[stk[top-1]],a[i],a[stk[top]]); int A=sign(B); if(A>=0) used[stk[top--]]=false; else break; } stk[++top]=i; used[i]=true; } for(int i=1;i<top;i++) convex.push_back(stk[i]); used[1]=false;used[n]=false; top=0; for(int i=n;i>=1;i--){ if(used[i]) continue; while(top>=2){ double B=area(a[stk[top-1]],a[i],a[stk[top]]); int A=sign(B); if(A>=0) used[stk[top--]]=false; else break; } stk[++top]=i; used[i]=true; } for(int i=1;i<top;i++) convex.push_back(stk[i]); double res=0; for(int i=0;i<convex.size();i++){ res+=get_len(a[convex[(i + 1) % convex.size()]] , a[convex[i]]); } return res; } void solve(){ cin>>n; for(int i=1;i<=n;i++){ cin>>a[i].x>>a[i].y; } double res=andrew(); cout<<fixed<<setprecision(2)<<res; } signed main(){ solve(); return 0; }
|