题目:http://www.nocow.cn/index.php/Translate:USACO/fc
求所有点的凸包的最小周长。
利用的是“卷包裹”算法:http://www.nocow.cn/index.php/Graham_Scan
算法描述如下:
- 找出一个必定会在凸包内的中点
- 计算每个点和中点的连线与x轴的夹角(在 0——360 度的范围内)
- 根据这些夹角对顶点排序
- 加入最初的两个顶点
- 对于除最后一个顶点以外的其余顶点
- 让其成为凸包上的下一个顶点
- 检查它和前面两个顶点组成的角是否大于 180 度
- 如果它和前面两个顶点组成的角大于 180 度,那么把它前面那个顶点删掉
- 加入最后一个顶点
- 完成上述的删除任务
- 检查最后一个顶点和它的前一个顶点和第一个顶点所组成的角是否大于 180 度,或者最后一个顶点和第一、第二个顶点组成的角是否大于 180 度。
- 如果第一种情况为真,删除最后一个顶点,并且检查倒数第二个顶点。
- 如果第二种情况为真,删除第一个顶点,继续检查。
- 当两种情况都不为真时,停止。
找出一个必定会在凸包内的中点 计算每个点和中点的连线与x轴的夹角(在 0——360 度的范围内) 根据这些夹角对顶点排序 加入最初的两个顶点 对于除最后一个顶点以外的其余顶点 让其成为凸包上的下一个顶点 检查它和前面两个顶点组成的角是否大于 180 度 如果它和前面两个顶点组成的角大于 180 度,那么把它前面那个顶点删掉 加入最后一个顶点 完成上述的删除任务 检查最后一个顶点和它的前一个顶点和第一个顶点所组成的角是否大于 180 度,或者最后一个顶点和第一、第二个顶点组成的角是否大于 180 度。 如果第一种情况为真,删除最后一个顶点,并且检查倒数第二个顶点。 如果第二种情况为真,删除第一个顶点,继续检查。 当两种情况都不为真时,停止。
但是我觉得:
- 找出一个必定会在凸包内的中点
- 计算每个点和中点的连线与x轴的夹角(在 0——360 度的范围内)
- 根据这些夹角对顶点排序
- 加入最初的两个顶点
- 对于除最后一个顶点以外的其余顶点
- 让其成为凸包上的下一个顶点
- 检查它和前面两个顶点组成的角是否大于 180 度
- 如果它和前面两个顶点组成的角大于 180 度,那么把它前面那个顶点删掉 ,继续判断
- 加入最后一个顶点
- 完成上述的删除任务
- 检查最后一个顶点和它的前一个顶点和第一个顶点所组成的角是否大于 180 度,或者最后一个顶点和第一、第二个顶点组成的角是否大于 180 度。
- 如果第一种情况为真,删除最后一个顶点,并且检查倒数第二个顶点。
- 如果第二种情况为真,删除第一个顶点,继续检查。
- 当两种情况都不为真时,停止。
如果没有继续判断的话,是会出错的。代码如下:
运行结果如下:
后来我看了别人的70行代码,自叹不如
速度也快了一个数量级, 这就是差距吗?