题意:求凸包直径。
分析:用graham按纵坐标序,再用旋转卡壳法。
但是模板我并没有完全理解,为什么要用点到直线的距离呢
View Code
#include <iostream>
#include <cstdlib>
#include <cstring>
#include <cstdio>
#include <algorithm>
usingnamespace std;
#define maxn 50005
struct Xpoint
{
int x, y;
} pnt[maxn], res[maxn];
int n;
bool mult(Xpoint sp, Xpoint ep, Xpoint op)
{
return (sp.x - op.x) * (ep. y - op.y) >= (ep.x - op.x) * (sp.y - op.y);
}
booloperator<(const Xpoint &l, const Xpoint &r)
{
return l.y < r. y || (l.y == r.y && l.x < r.x);
}
int cross(Xpoint a, Xpoint b, Xpoint o)
{
return (a.x - o.x) * (b.y - o.y) - (b.x - o.x) * (a.y - o.y);
}
int graham()
{
int i, len, top =1;
sort(pnt, pnt + n);
if (n ==0)
return0;
res[0] = pnt[0];
if (n ==1)
return1;
res[1] = pnt[1];
if (n ==2)
return2;
res[2] = pnt[2];
for (i =2; i < n; i++)
{
while (top && mult(pnt[i], res[top], res[top -1]))
top--;
res[++top] = pnt[i];
}
len = top;
res[++top] = pnt[n -2];
for (i = n -3; i >=0; i--)
{
while (top != len && mult(pnt[i], res[top], res[top -1]))
top--;
res[++top] = pnt[i];
}
return top;
}
int dist2(Xpoint a, Xpoint b)
{
return (a.x - b.x) * (a.x - b.x) + (a.y - b.y) * (a.y - b.y);
}
int rotating_calipers(Xpoint *ch, int n)
{
int q =1, ans =0;
ch[n] = ch[0];
for (int p =0; p < n; p++)
{
while (cross(ch[p +1], ch[q +1], ch[p]) > cross(ch[p +1], ch[q], ch[p]))
q = (q +1) % n;
ans = max(ans, max(dist2(ch[p], ch[q]), dist2(ch[p +1], ch[q +1])));
}
return ans;
}
int main()
{
//freopen("t.txt", "r", stdin);
scanf("%d", &n);
for (int i =0; i < n; i++)
scanf("%d%d", &pnt[i].x, &pnt[i].y);
int count = graham();
int ans = rotating_calipers(res, count);
printf("%d\n", ans);
return0;
}
#include <cstdlib>
#include <cstring>
#include <cstdio>
#include <algorithm>
usingnamespace std;
#define maxn 50005
struct Xpoint
{
int x, y;
} pnt[maxn], res[maxn];
int n;
bool mult(Xpoint sp, Xpoint ep, Xpoint op)
{
return (sp.x - op.x) * (ep. y - op.y) >= (ep.x - op.x) * (sp.y - op.y);
}
booloperator<(const Xpoint &l, const Xpoint &r)
{
return l.y < r. y || (l.y == r.y && l.x < r.x);
}
int cross(Xpoint a, Xpoint b, Xpoint o)
{
return (a.x - o.x) * (b.y - o.y) - (b.x - o.x) * (a.y - o.y);
}
int graham()
{
int i, len, top =1;
sort(pnt, pnt + n);
if (n ==0)
return0;
res[0] = pnt[0];
if (n ==1)
return1;
res[1] = pnt[1];
if (n ==2)
return2;
res[2] = pnt[2];
for (i =2; i < n; i++)
{
while (top && mult(pnt[i], res[top], res[top -1]))
top--;
res[++top] = pnt[i];
}
len = top;
res[++top] = pnt[n -2];
for (i = n -3; i >=0; i--)
{
while (top != len && mult(pnt[i], res[top], res[top -1]))
top--;
res[++top] = pnt[i];
}
return top;
}
int dist2(Xpoint a, Xpoint b)
{
return (a.x - b.x) * (a.x - b.x) + (a.y - b.y) * (a.y - b.y);
}
int rotating_calipers(Xpoint *ch, int n)
{
int q =1, ans =0;
ch[n] = ch[0];
for (int p =0; p < n; p++)
{
while (cross(ch[p +1], ch[q +1], ch[p]) > cross(ch[p +1], ch[q], ch[p]))
q = (q +1) % n;
ans = max(ans, max(dist2(ch[p], ch[q]), dist2(ch[p +1], ch[q +1])));
}
return ans;
}
int main()
{
//freopen("t.txt", "r", stdin);
scanf("%d", &n);
for (int i =0; i < n; i++)
scanf("%d%d", &pnt[i].x, &pnt[i].y);
int count = graham();
int ans = rotating_calipers(res, count);
printf("%d\n", ans);
return0;
}