凸包

https://www.luogu.com.cn/problem/P2742


//author:kzssCCC

#include <bits/stdc++.h>
using namespace std;
using ll = long long;
using ld = long double;

class point{
public:
	ld x,y;
};


ld cross(point& a,point& b,point& c){
	ld x1 = b.x-a.x;
	ld y1 = b.y-a.y;
	ld x2 = c.x-a.x;
	ld y2 = c.y-a.y;

	return x1*y2-x2*y1;
}

ld dis(point& a,point& b){
	return sqrt((a.x-b.x)*(a.x-b.x)+(a.y-b.y)*(a.y-b.y));
}


void solve(){
	int n;
	cin >> n;

	vector<point> a(n);
	for (int i=0;i<n;i++){
		cin >> a[i].x >> a[i].y;	
	}

	sort(a.begin(),a.end(),[&](point& p1,point& p2){
		if (p1.x!=p2.x) return p1.x<p2.x;
		return p1.y<p2.y;
	});


	vector<point> stk;
	int tot = 0;

	//构建下凸包
	for (int i=0;i<n;i++){
		while (tot>=2 && cross(stk[tot-2],stk[tot-1],a[i])<=0){
			stk.pop_back();
			tot--;
		}
		stk.push_back(a[i]);
		tot++;
	}

	int t = tot;

	//构建上凸包
	for (int i=n-1;i>=0;i--){
		while (tot-t>=2 && cross(stk[tot-2],stk[tot-1],a[i])<=0){
			stk.pop_back();
			tot--;
		}
		stk.push_back(a[i]);
		tot++;
	}

	ld res = 0;

	for (int i=1;i<tot;i++){
		res += dis(stk[i],stk[i-1]);
	}

	cout << fixed << setprecision(2) << res << '\n';
}

int main(){
	ios::sync_with_stdio(false);
	cin.tie(0);
	
	int t = 1;
	// cin >> t;
	while (t--) solve();

	return 0;
}
posted @ 2026-04-14 00:46  kzssCCC  阅读(4)  评论(0)    收藏  举报