凸包问题

思想: 找一些点 然后把这些点连接起来 形成的图形 可以把所有点包含

 

大佬的博客:数学:凸包算法详解

 

例题:洛谷那个模板题

代码:

#include <bits/stdc++.h>
using namespace std;
#define M 100005
#define ri register int

struct dian{
    double x,y;
}p[M];

bool cmp1(dian a,dian b)
{
    if(a.y==b.y) return a.x<b.x;
    return a.y<b.y;
}
bool cmp2(dian a,dian b)
{
    if(atan2(a.y-p[1].y,a.x-p[1].x)==atan2(b.y-p[1].y,b.x-p[1].x)) return a.x<b.x;
    return atan2(a.y-p[1].y,a.x-p[1].x)<atan2(b.y-p[1].y,b.x-p[1].x);
}
double ck(int a,int b,int c)
{
    return (p[b].x-p[a].x)*(p[c].y-p[a].y)-(p[c].x-p[a].x)*(p[b].y-p[a].y);
}
double dis(int a,int b)
{
    return sqrt((p[a].x-p[b].x)*(p[a].x-p[b].x)+(p[a].y-p[b].y)*(p[a].y-p[b].y));
}
int n,m;
int q[M];
int main(){
    
    scanf("%d",&n);
    for(ri i=1;i<=n;i++)
    scanf("%lf%lf",&p[i].x,&p[i].y);
    
    sort(p+1,p+1+n,cmp1);
    int top=1;
    q[top]=1;
    sort(p+2,p+1+n,cmp2);
    q[++top]=2;
    
    for(ri i=3;i<=n;i++)
    {
        while(top>=2&&ck(q[top-1],q[top],i)<=0)
        top--;
        q[++top]=i;
    }
    double ans=0;
    for(ri i=2;i<=top;i++)
    {
        ans+=dis(q[i],q[i-1]);
    }
    ans+=dis(q[top],1);
    printf("%0.2lf",ans);
    return 0;
    
}
View Code

 

细节: 1 sort 的 cmp 是结构体 那就定义 结构体。

            2 叉积

            3 运用了 队列 或者 数组 的时候 ,一定要用队列的东西,而不是 用 i (表示队列的第几个元素)是 去q[i],p[i],q[top],而不是top

   

 

posted @ 2021-11-30 10:42  VxiaohuanV  阅读(29)  评论(0编辑  收藏  举报