二维凸包模板
其实二维凸包是个很简单的东西
想象一下我们在二维平面上打了很多柱子,凸包其实就是往上面套橡皮筋,收到最紧就是了
我们把这些桩子按照x,y从小到大排序
发现什么呢?数组内第一个和最后一个点一定在凸包上
为什么呢?我们来思考一下第一个桩子
如果它不在橡皮筋上,那它左边肯定得有人帮他撑着呢
但是?没有啊!
末尾的柱子同理,右边没有柱子给他撑着
那我们咋找凸包呢?
我们把凸包用左右两个端点分成两个部分,向上凸叫上凸包,下凸包同理
如何找下凸包?
想象一下下凸包的形状,不难发现这些线段的斜率都是不断上升的
于是我们把每个点入栈,如果发现加入这个点,和之前的点构成的斜率不是递增的,就把上一个点扔了
为什么不把当前点扔了呢?扔了前面的点,目前点可以包含之前的,反之不可以
上凸包对称操作即可
代码:
// Problem: P2742 [USACO5.1]圈奶牛Fencing the Cows /【模板】二维凸包
// Contest: Luogu
// URL: https://www.luogu.com.cn/problem/P2742
// Memory Limit: 128 MB
// Time Limit: 1000 ms
//
// Powered by CP Editor (https://cpeditor.org)
#include <bits/stdc++.h>
#include <bits/extc++.h>
#define INF 0x7fffffff
#define MAXN 100005
#define MAXM 10003
#define eps 1e-9
#define foru(a,b,c) for(int a=b;a<=c;a++)
#define ford(a,b,c) for(int a=b;a>=c;a--)
#define RT return 0;
#define db(x) cout<<endl<<x<<endl;
#define LL long long
#define LXF int
#define RIN rin()
#define HH printf("\n")
using namespace std;
inline LXF rin(){
LXF x=0,w=1;
char ch=0;
while(ch<'0'||ch>'9'){
if(ch=='-') w=-1;
ch=getchar();
}
while(ch>='0'&&ch<='9'){
x=x*10+(ch-'0');
ch=getchar();
}
return x*w;
}
inline void out(LXF x){
if(x<0){
x=-x;
putchar('-');
}
if(x>9) out(x/10);
putchar(x%10+'0');
}
struct Pos{
double x,y;
}a[MAXN],s[MAXN];
int n;
double ans;
int top=0;
double dis(Pos p,Pos q){
return sqrt((q.x-p.x)*(q.x-p.x)+(q.y-p.y)*(q.y-p.y));
}
double getk(Pos p,Pos q){
return (q.y-p.y)/(q.x-p.x);
}
bool cmp(Pos p,Pos q){
return p.x!=q.x?p.x<q.x:p.y<q.y;
}
int main(){
scanf(" %d",&n);
for(int i=1;i<=n;i++){
scanf(" %lf %lf",&a[i].x,&a[i].y);
}
sort(a+1,a+1+n,cmp);
for(int i=1;i<=n;i++){
s[++top]=a[i];
while(top>=3&&getk(s[top-1],s[top])<getk(s[top-2],s[top-1])){
top-=2;
s[++top]=a[i];
}
}
for(int i=2;i<=top;i++){
ans+=dis(s[i-1],s[i]);
}
top=0;
for(int i=1;i<=n;i++){
s[++top]=a[i];
while(top>=3&&getk(s[top-1],s[top])>getk(s[top-2],s[top-1])){
top-=2;
s[++top]=a[i];
}
}
for(int i=2;i<=top;i++){
ans+=dis(s[i-1],s[i]);
}
printf("%.2lf",ans);
return 0;
}
标签:double,top,Pos,凸包,二维,define
From: https://www.cnblogs.com/XHZS-XY/p/16593330.html