CGL_4_A:Convex Hull 凸包的andrew算法

题目链接

题目给出一个多边形,要求出这个多边形的凸包;

在一个点集D中,按一定顺序选取子集Q 
使得Q中所有点顺次连接所构成的封闭凸多边形包住D中所有点

可以形象地理解为:有许多个钉子钉在平面上,用一根牛皮筋把所有点包住 

 

找出凸包的思路是:

先把题目给出的多边形的点集合按x坐标从小到大排序,x相同的按y从小到大排序;(点的<前面已经重载过,符合这个要求)

将排序后的集合遍历,先把2个放入栈u中,如果新加入一个点后,能保证u中的点仍然是凸包的,就加进去,否则就pop出来一个点,直到u成为一个凸包为止;这样就得到了凸包的上半部分;

再把点按照x从大到小排序,x相同的y从大到小排序;

其他的操作同上,由此得到凸包的下半部分。

最后,把上下两部分合并(按照要求,本题是要求逆时针方向输出生成凸包中的点)

 

凸包的得到过程如下:

Polygon scan(Polygon S){
	sort(S.begin(),S.end());
	Polygon u,t;
	if (S.size() < 3) return S;
	int len=S.size();
	u.push_back(S[0]);
	u.push_back(S[1]);
	t.push_back(S[S.size()-1]);
	t.push_back(S[S.size()-2]);
	for(int i=2;i<len;i++){
		for(int j=u.size();j>=2&&(ccw(u[j-2], u[j-1], S[i])==COUNTER_CLOCKWISE);j--){
			u.pop_back();
		}
		u.push_back(S[i]);
	}
	for(int i=len-3;i>=0;i--){
		for(int j=t.size();j>=2&&(ccw(t[j-2],t[j-1],S[i])==COUNTER_CLOCKWISE);j--){
			t.pop_back();
		}
		t.push_back(S[i]);
	}
	
	reverse(t.begin(), t.end());
	for (int i = u.size() - 2; i >= 1; i--)
		t.push_back(u[i]);

	return t;
}

构建完成凸包后,按照题目要求输出即可

题目代码如下:

int cmp(Point A, Point B)                     //竖直排序  
{
	return (A.y<B.y || (A.y == B.y&&A.x<B.x));
}

int main (){
	Polygon g, ans ,temp;
	Point t;
	int n, len;
	scanf("%d", &n);
	for (int i = 0; i < n; i++) {
		scanf("%lf %lf", &t.x, &t.y);
		g.push_back(t);
	}
	ans = scan(g);

	temp = ans;
	// 选出最左侧最下端的点开始输出
	sort(temp.begin(), temp.end(),cmp);
	int index;
	for (int i = 0; i < ans.size(); i++)
		if (ans[i] == temp[0])
			index = i;
	cout<<ans.size()<<endl;
	for (int i = 0; i < ans.size(); i++)
		printf("%d %d\n", int(ans[(i + index) % ans.size()].x), 
			int(ans[(i + index) % ans.size()].y));
	return 0;
	
}

错点:

1.输出的时候以凸多边形最下端最左侧的顶点为起点,按逆时针方向依次输出坐标;

  • 1
    点赞
  • 0
    收藏
    觉得还不错? 一键收藏
  • 0
    评论

“相关推荐”对你有帮助么?

  • 非常没帮助
  • 没帮助
  • 一般
  • 有帮助
  • 非常有帮助
提交
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值