凸包问题
思想: 找一些点 然后把这些点连接起来 形成的图形 可以把所有点包含
大佬的博客:数学:凸包算法详解
例题:洛谷那个模板题
代码:
#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; }
细节: 1 sort 的 cmp 是结构体 那就定义 结构体。
2 叉积
3 运用了 队列 或者 数组 的时候 ,一定要用队列的东西,而不是 用 i (表示队列的第几个元素)是 去q[i],p[i],q[top],而不是top