SMU Winter 2024 div2 ptlks的周报Week 4(2.19-2.25)

凸包

P2742

二维凸包的模版题,主要通过Graham算法维护凸包点集,将凸包作为上下两部分分别维护

#include <bits/stdc++.h> 

using namespace std;
bool cmp(vector<double> x,vector<double> y);
bool judge(vector<double> x,vector<double> y,vector<double> z);
double distan(vector<double> x,vector<double> y);


int main(){
	int n;
	vector<vector<double> > a;
	cin>>n;
	int t[n],d[n];
	for(int i=0;i<n;i++)t[i]=-1;
	for(int i=0;i<n;i++){
		double x,y;
		cin>>x>>y;
		if(i+1>a.size()){
			a.resize(a.size()+1);
			a[i].resize(2);
		}
		a[i][0]=x;
		a[i][1]=y;
	}
	sort(a.begin(),a.end(),cmp);
	//上部 
	t[0]=0;
	t[1]=1;
	int lt=2;
	for(int i=2;i<a.size();i++){
		for(int j=lt;j>=2&&!judge(a[t[j-2]],a[t[j-1]],a[i]);j--){
			lt--;
		}
		t[lt]=i;
		lt++;
	}
	//下部 
	d[0]=a.size()-1;
	d[1]=a.size()-2;
	int ld=2;
	for(int i=a.size()-3;i>=0;i--){
		for(int j=ld;j>=2&&!judge(a[d[j-2]],a[d[j-1]],a[i]);j--){
			ld--;
		}
		d[ld]=i;
		ld++;
	}
	for(int i=1;i<lt-1;i++){
		d[ld]=t[i];
		ld++;
	}
	double s=0;
	for(int i=0;i<ld;i++){
		if(i<ld-1){
			s+=distan(a[d[i]],a[d[i+1]]);
		}else {
			s+=distan(a[d[i]],a[d[0]]);
		}
	}
	printf("%.2lf",s);
	return 0;
}

bool cmp(vector<double> x,vector<double> y){
	if(x[0]!=y[0])return x[0]<y[0];
	else return x[1]<y[1];
}

double cross(double x[],double y[]){
	return x[0]*y[1]-x[1]*y[0];
}

bool judge(vector<double> x,vector<double> y,vector<double> z){
	double a[2];
	a[0]=x[0]-z[0];
	a[1]=x[1]-z[1];
	double b[2];
	b[0]=y[0]-z[0];
	b[1]=y[1]-z[1];
	return cross(a,b)>0;
}

double distan(vector<double> x,vector<double> y){
	return sqrt((x[0]-y[0])*(x[0]-y[0])+(x[1]-y[1])*(x[1]-y[1]));
}
posted @ 2024-02-25 15:20  ptlks  阅读(11)  评论(0编辑  收藏  举报