# 旋转卡壳（1）--求凸包（点集）直径

1.

2.

Compute the polygon's extreme points in the y direction. Call them ymin and ymax. Construct two horizontal lines of support through ymin and ymax. Since this is already an anti-podal pair, compute the distance, and keep as maximum. Rotate the lines until one is flush with an edge of the polygon. A new anti-podal pair is determined. Compute the new distance, compare to old maximum, and update if necessary. Repeat steps 3 and 4 until the anti-podal pair considered is (ymin,ymax) again. Output the pair(s) determining the maximum as the diameter pair(s).

 1 double rotating_calipers(Point *ch,int n)
2 {
3     int q=1;
4     double ans=0;
5     ch[n]=ch[0];
6      for(int p=0;p<n;p++)
7 {
8       while(cross(ch[p+1],ch[q+1],ch[p])>cross(ch[p+1],ch[q],ch[p]))
9             q=(q+1)%n;
10     ans=max(ans,max(dist(ch[p],ch[q]),dist(ch[p+1],ch[q+1])));
11      }
12 return ans;
13 } 

poj 2187 ：http://poj.org/problem?id=2187

#include<iostream>
#include<cstdio>
#include<cstring>
#include<algorithm>
#include<cmath>
#define N 50005
using namespace std;
struct point
{
int x,y;
}p[N];
int top,n,s[N];
int cross(point a,point b,point c)//叉积
{
return (b.x - a.x) * (c.y - a.y) - (c.x - a.x) * (b.y - a.y);
}

int dis(point a,point b)//距离
{
return (a.x - b.x) * (a.x - b.x) + (a.y - b.y) * (a.y - b.y);
}

bool cmp(point a,point b)
{
int ans = cross(p[0],a,b);
if( ans > 0 || (ans == 0 && dis(p[0],a) > dis(p[0],b) )) return true;
return false;
}

void graham()//凸包模板。。
{
s[0] = 0;
s[1] = 1;
top = 1;
for(int i = 2;i != n ;i ++)
{
while(top && cross(p[s[top - 1]],p[s[top]],p[i] ) < 0) top--;
s[++top] = i;
}
top ++;
}

void RC()//旋转卡壳
{
int q,p1,pp,qq,rr,r,ans = 0;
q = 1;
ans = dis(p[s[0]],p[s[1]]);
for(int i = 0; i != top ;i ++)
{
while(abs(cross(p[s[(i+1)%top]],p[s[i%top]],p[s[(q+1)%top]])) > abs(cross(p[s[(i+1)%top]],p[s[i%top]],p[s[q%top]]))) q = (q + 1)%top;
ans = max(ans , max(dis(p[s[(i+1)%top]],p[s[q]]),dis(p[s[i%top]],p[s[q]])));
}
printf("%d\n",ans);
}

int main()
{
while(~scanf("%d",&n))
{
for(int i =0 ;i != n;i ++) scanf("%d%d",&p[i].x,&p[i].y);
int u = 0;
for(int i = 1;i != n;i ++)//寻找基点
{
if(p[u].y > p[i].y || (p[u].y == p[i].y && p[u].x > p[i].x)) u = i;
}
if(u)
{
swap(p[u].y,p[0].y);
swap(p[u].x,p[0].x);
}
sort(p + 1,p + n,cmp);
graham();
RC();
}
return 0;
}

• 广告
• 抄袭
• 版权
• 政治
• 色情
• 无意义
• 其他

120