题意:给定二维平面上不超过50000个点,求最远点对距离的平方。
思路:由数据量来判断直接枚举会超时。注意到最远距离点对必出现在这些点的凸包上,所以可以先求出凸包,然后在凸包上枚举。此法的最坏情况复杂度仍然是n^2的,但是可以AC这道题了。在复杂度意义下的优化是旋转卡壳(参考http://www.cppblog.com/staryjy/archive/2009/11/19/101412.html):

如果qa,qb是凸包上最远两点,必然可以分别过qa,qb画出一对平行线。通过旋转这对平行线,我们可以让它和凸包上的一条边重合,如图中蓝色直线,可以注意到,qa是凸包上离p和qb所在直线最远的点。于是我们的思路就是枚举凸包上的所有边,对每一条边找出凸包上离该边最远的顶点,计算这个顶点到该边两个端点的距离,并记录最大的值。直观上这是一个O(n2)的算法,和直接枚举任意两个顶点一样了。但是注意到当我们逆时针枚举边的时候,最远点的变化也是逆时针的,这样就可以不用从头计算最远点,而可以紧接着上一次的最远点继续计算(详细的证明可以参见上面链接中的论文)。于是我们得到了O(n)的算法。
凸包上枚举:
#include <cstdio>
#include <cstring>
#include <algorithm>
#include <cmath>
#include <queue>
#include <cstdlib>
using namespace std;
#define clc(s,t) memset(s,t,sizeof(s))
#define INF 0x3fffffff
#define N 50005
struct point{
int x,y;
}p[N];
i

最低0.47元/天 解锁文章

被折叠的 条评论
为什么被折叠?



