P1452 旋转卡壳
题面 给定平面n个点,求凸包直径(输出凸包直径的平方) 2 < = n < = 50000 2<=n<=50000 2 < = n < = 5 0 0 0 0 (实测存在一列点构成直线的数据) 分析 凸包直径:凸包两两顶点间最远的距离 容易想到O(n 2 )的方法, 求出凸包 后遍历顶点对求距离max即可 但有更优的做法,遍历的一个点移动一次,其对面的点(对踵点)移动的幅度并不会太大,并且旋转方向相同(同顺时针或同逆时针),所以其实存在O(N)的做法。 这种遍历一般有两种:点-点遍历,边-点遍历: 第二种在代码上实现更容易(第一种貌似有特例,如特别扁的图形,会失去长度的单峰性) 过程即start边在凸包上移动,分别找出每个start边的最远opposite点。这个最远可以用三角形面积来衡量,如图上的那样,根据平行线的知识,过其他顶点作start边的平行线,最远的平行线可以使三角形面积最大,也就是最远的点。这时计算这个最远点与start两端点的距离取max即得出当前start边下能得到的最大直径。对所有start边下的直径取max即是全局最大直径。 如何快速找出对每一个start最远的opposite?如果单纯遍历仍然会落入O(n 2 )。而通过观察同一start下三角形的面积是一个单峰函数(平行线从近到远再到近),并且已知start移动一次,这个峰移动不会太大,而且是同向移动