凸包

二维凸包

定义

凸多边形

凸多边形是指所有内角大小都在 范围内的 简单多边形

凸包

在平面上能包含所有给定点的最小凸多边形叫做凸包。

其定义为:对于给定集合X ,所有包含 X 的凸集的交集 S 被称为 X 的 凸包

实际上可以理解为用一个橡皮筋包含住所有给定点的形态。

凸包用最小的周长围住了给定的所有点。如果一个凹多边形围住了所有的点,它的周长一定不是最小,如下图。根据三角不等式,凸多边形在周长上一定是最优的。

Andrew 算法求凸包

常用的求法有 Graham 扫描法和 Andrew 算法,这里主要介绍 Andrew 算法。

 

#include <bits/stdc++.h>
using namespace std;
signed main()
{
long long n,l;
cin>>n>>l;
vector<pair<long long,long long> >e;
for(long long i=1;i<=n;i++)
{
long long a,b;
cin>>a>>b;
e.push_back({a,b});
}
sort(e.begin(),e.end());
long long st1[1010];
vector<long long>visited(n+1);
long long top1=0;
st1[++top1]=0;
for(long long i=1;i<n;i++)
{
while(top1>1)
{
pair<long long,long long>a=e[st1[top1]],b=e[st1[top1-1]];
pair<long long,long long>x={a.first-b.first,a.second-b.second};
pair<long long,long long>y={e[i].first-a.first,e[i].second-a.second};
if(x.first*y.second-x.second*y.first<=0)
{
visited[st1[top1]]=0;
top1--;
}
else break;
}
st1[++top1]=i;
visited[i]=1;
}
long long st2[1010];
long long top2=0;
st2[++top2]=st1[top1];
for(long long i=n-1;i>=0;i--)
{
if(!visited[i])
{
while(top2>1)
{
pair<long long,long long>a=e[st2[top2]],b=e[st2[top2-1]];
pair<long long,long long>x={a.first-b.first,a.second-b.second};
pair<long long,long long>y={e[i].first-a.first,e[i].second-a.second};
if(x.first*y.second-x.second*y.first<=0)
{
visited[st2[top2]]=0;
top2--;
}
else break;
}
st2[++top2]=i;
visited[i]=1;
}
}
long double sum=0;
for(long long i=2;i<=top1;i++)
{
sum+=sqrt((e[st1[i]].first-e[st1[i-1]].first)*(e[st1[i]].first-e[st1[i-1]].first)+(e[st1[i]].second-e[st1[i-1]].second)*(e[st1[i]].second-e[st1[i-1]].second));
}
for(long long i=2;i<=top2;i++)
{
sum+=sqrt((e[st2[i]].first-e[st2[i-1]].first)*(e[st2[i]].first-e[st2[i-1]].first)+(e[st2[i]].second-e[st2[i-1]].second)*(e[st2[i]].second-e[st2[i-1]].second));
}
sum+=2.0*acos(-1)*l;
sum+=0.5;
long long ans=sum;
cout<<ans;
}
posted @ 2023-08-12 11:28  sleepaday  阅读(21)  评论(0编辑  收藏  举报