[luogu1452]Beauty Contest凸包+旋转卡壳
Posted chhokmah
tags:
篇首语:本文由小常识网(cha138.com)小编为大家整理,主要介绍了[luogu1452]Beauty Contest凸包+旋转卡壳相关的知识,希望对你有一定的参考价值。
题目大意
求出平面最远点对距离的平方。
分析
此题我wa了好久,第一是凸包写错了,后面又是旋转卡壳写错了。。自闭3s。
题解应该是旋转卡壳,但是有人用随机化乱搞过掉了Orz。
讲讲正解。
我们先求出所有点的凸包,然后每一次更新对踵点,就像一个尺子一样卡着这个凸包的每一条边,然后计算两个点对之间的距离就可以了。
代码(借鉴了一下别人的代码)
#include <bits/stdc++.h>
#define ll long long
#define ms(a, b) memset(a, b, sizeof(a))
#define inf 0x3f3f3f3f
#define db double
#define N 50005
#define Vector2 Point
using namespace std;
template <typename T>
inline void read(T &x) {
x = 0; T fl = 1; char ch = 0;
for (; ch < '0' || ch > '9'; ch = getchar())
if (ch == '-') fl = -1;
for (; ch >= '0' && ch <= '9'; ch = getchar())
x = (x << 1) + (x << 3) + (ch ^ 48);
x *= fl;
}
template <typename T> T sqr(T x) { return x * x; }
struct Point {
ll x, y;
}P[N], S[N];
int tot = 0;
ll Dist(Point p1, Point p2) {
return sqr(p1.x - p2.x) + sqr(p1.y - p2.y);
}
Vector2 operator -(Vector2 v1, Vector2 v2) {
return (Vector2){v1.x - v2.x, v1.y - v2.y};
}
ll Cross(Vector2 v1, Vector2 v2) {
return v1.x * v2.y - v1.y * v2.x;
}
bool cmp(Point p1, Point p2) {
if (Cross(p1 - P[1], p2 - P[1]) < 0) return 0;
if (Cross(p1 - P[1], p2 - P[1]) > 0) return 1;
return Dist(P[1], p1) < Dist(P[1], p2);
}
bool check(Point p1, Point p2, Point p3, Point p4) {
return Cross(p2 - p1, p4 - p3) <= 0;
}
void Get_Hull(Point *P, int n) {
sort(P + 2, P + 1 + n, cmp);
tot = 0;
S[++ tot] = P[1];
for (int i = 2; i <= n; i ++) {
while (tot > 1 && check(S[tot - 1], S[tot], S[tot], P[i])) -- tot;
S[++ tot] = P[i];
}
S[tot + 1] = S[1];
}
int n;
ll Rotate_Get_ans() {
if (tot == 1) return 0;
if (tot == 2) return Dist(S[1], S[2]);
ll j = 2, ans = 0;
for (int i = 1; i <= tot; i ++) {
while (Cross(S[i + 1] - S[i], S[j] - S[i + 1]) <= Cross(S[i + 1] - S[i], S[j + 1] - S[i + 1])) j = j == tot ? 1 : j + 1;
ans = max(ans, max(Dist(S[i], S[j]), Dist(S[i + 1], S[j])));
}
return ans;
}
int main() {
read(n);
for (int i = 1; i <= n; i ++) {
scanf("%lld%lld", &P[i].x, &P[i].y);
if (P[i].y < P[1].y || (P[i].y == P[1].y && P[i].x < P[1].x)) swap(P[i], P[1]);
}
Get_Hull(P, n);
printf("%lld\n", Rotate_Get_ans());
return 0;
}
以上是关于[luogu1452]Beauty Contest凸包+旋转卡壳的主要内容,如果未能解决你的问题,请参考以下文章
POJ2187 Beauty Contest 水平序GrahamScan法