这个题用旋转卡壳做的,对于问题规模比较大时就可以体现出来他的优势了。凸包上的点依次与对应边产生的距离成单峰函数,
我们首先固定一条边,然后找到第一个k,使得(i,j,k)的叉积<(i,j,k+1)的叉积,这时更新最大值,然后枚举下一个边,
这个复杂度是O(n)的,因为我们逆时针枚举边的时候,k也是逆时针变化的。
关键代码:
void rotating_calipers() { int ans=0,d1,d2; int i,k; s[top+1]=s[0]; k=1; for(i=0;i<=top;++i) { while(cros(s[i],s[i+1],s[k])<cros(s[i],s[i+1],s[k+1])) k=(k+1)%(top+1); d1=dis(s[i],s[k]); d2=dis(s[i+1],s[k]); if(d1>ans) ans=d1; if(d2>ans) ans=d2; } cout<<ans<<endl; }