POJ 1873 & 1228 凸包和稳定凸包

来源:互联网 发布:知商金融预警 编辑:程序博客网 时间:2024/06/06 02:32

凸包指的是这么一件事:平面上有好多点,你希望用一些点围成一个尽量小的凸多边形,然后把所有的点都框住。求凸包是很有用的,往往会作为解计算几何题目的第一步。


求凸包一般用Graham算法,它是NlgN的算法,非常简单。基本步骤就是先极角排序,然后从第一个点开始,每次向下一个点连一条向量,如果这条向量和之前已经加入凸包的点的点之间出现凹进去的部分了,就把之前的点踢掉。由于每个点只进出凸包一次,所以扫描复杂度是N,这样就是NlgN的复杂度。


如果三点共线的话,凸包应该只包含两侧的点。


求凸包时有这么几点需要注意:


第一,模板中的list数组每次求凸包之后都会把点排序,因此像POJ 1873这种需要带上搜索的,就不能直接在list数组里搞,会乱掉的。

第二,list数组中不能有两个重复的点,否则这两个构成0向量,怎么弄也弄不掉。

第三,当点数小于3的时候需要小心,不过这个模板里已经处理了这种情况了。


POJ 1228实际上是个“稳定凸包问题”,稳定凸包说的是,如果在一个凸包外面再加一点,能否构成面积更大的凸包,如果能,则之前的凸包就是不稳定的。凸包稳定的充要条件是凸包的每一条边上都有3个或以上的点,这很容易想,如果只有两个点的话,就像拉皮筋一样,往外一拉就是一个更大的凸包了。如果有3个点的话,往外一拉,就会有凹的地方出现,就不是凸包了。


POJ 1228由于给你的点本身已经是一个有多余点的凸包了,所以我的做法是:将所有点逆时针排序,然后检查是否有两个连续的拐角就可以了。检查两个连续的拐角,只需要检查是否有两个连续的点,每个点相邻的两条向量夹角不为0就可以了。


但是WA得我不能理解,后来规定排序的时候先找到最左下角的点,然后排序,就对了……


而且不知道有没有NlgN做逆时针排序的算法? 

0 0
原创粉丝点击