凸包 代码专讲

参考文 《矢量的凸包应用》
这里专讲代码。
向量乘法代码

inline int con(node a, node b, node c) {
	return (c.x-a.x)*(b.y-a.y)-(c.y-a.y)*(b.x-a.x);
}

其实也是蛮好记的。


求两点距离

inline double dis(node a, node b) {
	return sqrt((a.x-b.x)*(a.x-b.x)+(a.y-b.y)*(a.y-b.y));
}

向量乘法参与运算时,要记得右手法则
拇指表示正负,其他四指表示旋转方向。

根据刚刚的向量积,可以推导得到,如果 a b → \overrightarrow{ab} ab a c → \overrightarrow{ac} ac 的逆时针方向,那么 a b → × a c → &lt; 0 \overrightarrow{ab}\times\overrightarrow{ac}&lt;0 ab ×ac <0
如果是顺时针那么 a b → × a c → &gt; 0 \overrightarrow{ab}\times\overrightarrow{ac}&gt;0 ab ×ac >0
如果共线则 a b → × a c → = 0 \overrightarrow{ab}\times\overrightarrow{ac}=0 ab ×ac =0
——《矢量的凸包应用》

于是非常容易得出比较函数

inline bool cmp(node b, node c) {
	int ans=con(a[1], b, c);
	if(ans) return ans>0;//bxc>0,则b在c顺时针方向
	return dis(b, a[1])<dis(c, a[0]);
}

来看主函数

求开始点

for(int i=1; i<=n; i++) {
		scanf("%d%d", &a[i].x, &a[i].y);
		if(a[mix].y>a[i].y||(a[mix].y==a[i].y&&a[mix].x>a[i].x)) mix=i;//求出第一个点
}

排序

swap(a[1], a[mix]);
sort(a+2, a+n+1, cmp);//排序

栈操作

	for(int i=3; i<=n; i++) {
		while(top&&con(st[top-1], a[i], st[top])>=0) {
			top--;//上一个点不对
		}
		st[++top]=a[i];
	}

赠品:求凸多边形面积

	int ans=0;
	for(int i=0; i<=top; i++) {
		ans+=(st[(i+1)%(top+1)].x*st[i].y-st[(i+1)%(top+1)].y*st[i].x)/2;
	}
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值