社区讨论
WA #16 求助
P1452【模板】旋转卡壳 / [USACO03FALL] Beauty Contest G参与者 2已保存回复 2
讨论操作
快速查看讨论及其快照的属性,并进行相关操作。
- 当前回复
- 2 条
- 当前快照
- 1 份
- 快照标识符
- @mhjtuap3
- 此快照首次捕获于
- 2025/11/04 08:24 4 个月前
- 此快照最后确认于
- 2025/11/04 08:24 4 个月前
CPP
#include <bits/stdc++.h>
#ifndef ONLINE_JUDGE
#define debug(...) cerr << format(__VA_ARGS__)
#else
#define debug(...)
#endif
using namespace std;
template<typename T> void ckmax(T& a, T b) { if (a < b) a = b; }
template<typename T> void ckmin(T& a, T b) { if (b < a) a = b; }
#ifndef PROGRAM_MAIN_CALC_GEOM_CS_
#define PROGRAM_MAIN_CALC_GEOM_CS_
namespace cg {
using f64 = double;
using i64 = int64_t;
constexpr f64 eps = 1e-8;
int sgn(f64 a) {
return (a > eps) - (a < -eps);
}
int sgn(i64 a) {
return (a > 0) - (a < 0);
}
template<typename T>
struct point {
T x, y;
point() {}
point(T x_, T y_): x{x_}, y{y_} {}
template<typename U>
point(const point<U>& o): x{static_cast<T>(o.x)}, y{static_cast<T>(o.y)} {};
template<typename U>
point(point<U>&& o): x{static_cast<T>(o.x)}, y{static_cast<T>(o.y)} {};
template<typename U>
point<T>& operator=(const point<U>& o) {x = static_cast<T>(o.x); y = static_cast<T>(o.y); return *this;}
template<typename U>
point<T>& operator=(point<T>&& o) {x = static_cast<T>(o.x); y = static_cast<T>(o.y); return *this;}
template<typename U>
auto operator+(point<U> other) -> point<decltype(x + other.x)> {
return point<decltype(x + other.x)>(x + other.x, y + other.y);
}
template<typename U>
auto operator-(point<U> other) -> point<decltype(x - other.x)> {
return point<decltype(x - other.x)>(x - other.x, y - other.y);
}
template<typename U>
auto operator*(U k) -> point<decltype(x * k)> {
return point<decltype(x * k)>(x * k, y * k);
}
template<typename U>
auto operator/(U k) -> point<decltype(x / k)> {
return point<decltype(x / k)>(x / k, y / k);
}
template<typename U>
bool operator==(point<U> other) {
return sgn(x - other.x) == 0 && sgn(y - other.y) == 0;
}
};
template<typename T>
using vctor = point<T>;
template<typename T>
T dot(vctor<T> a, vctor<T> b) {
return a.x * b.x + a.y * b.y;
}
template<typename T>
T cross(vctor<T> a, vctor<T> b) {
return a.x * b.y - a.y * b.x;
}
template<typename T>
T sqr(T a) {
return a * a;
}
template<typename T>
f64 dist_sqrt(point<T> a, point<T> b) {
return hypot(a.x - b.x, a.y - b.y);
}
template<typename T>
T dist_sqr(point<T> a, point<T> b) {
return sqr(a.x - b.x) + sqr(a.y - b.y);
}
template<typename T>
struct line {
point<T> a, b;
line() {}
line(point<T> c, point<T> d): a(c), b(d) {}
line(f64 c, f64 d, f64 e) {
if (sgn(c) == 0) {
a = point<T>(0, -c/b);
b = point<T>(1, -c/b);
} else if (sgn(b) == 0) {
a = point<T>(-c/a, 0);
b = point<T>(-c/a, 1);
} else {
a = point<T>(0, -c/b);
b = point<T>(1, (-c-a)/b);
}
}
template<typename U>
line(const line<U>& o): a(o.a), b(o.b) {}
template<typename U>
line(line<U>&& o): a(o.a), b(o.b) {}
template<typename U>
line<T>& operator=(const line<U>& o) {a = o.a; b = o.b; return *this;}
template<typename U>
line<T>& operator=(line<U>&& o) {a = move(o.a); b = move(o.b); return *this;}
};
template<typename T>
using segment = line<T>;
template<typename T>
f64 dist_point_line(point<T> a, line<T> b) { // 面积 / 底
return fabs(cross(b.a - a, b.b - a)) / dist_sqrt(b.a, b.b);
}
}
#endif
using i64 = int64_t;
int N;
vector<cg::point<i64>> a, d_line, u_line;
int main() {
ios::sync_with_stdio(false);
cin.tie(nullptr);
cin >> N;
a.resize(N);
for (int i = 0; i < N; ++i) {
cin >> a[i].x >> a[i].y;
}
ranges::sort(a, [&](const cg::point<i64>& a, const cg::point<i64>& b) {return cg::sgn(a.x - b.x) < 0 || (cg::sgn(a.x - b.x) == 0 && cg::sgn(a.y - b.y) < 0);});
for (int i = 0; i < N; ++i) {
int len_d = static_cast<int>(d_line.size());
while (len_d >= 2 && cg::cross(d_line[len_d - 1] - d_line[len_d - 2], a[i] - d_line[len_d - 1]) <= 0) {
d_line.pop_back();
--len_d;
}
d_line.push_back(a[i]);
}
for (int i = N - 1; i >= 0; --i) {
int len_u = static_cast<int>(u_line.size());
while (len_u >= 2 && cg::cross(u_line[len_u - 1] - u_line[len_u - 2], a[i] - u_line[len_u - 1]) <= 0) {
u_line.pop_back();
--len_u;
}
u_line.push_back(a[i]);
}
if (u_line.front() == d_line.back()) d_line.pop_back();
if (d_line.front() == u_line.back()) u_line.pop_back();
vector<cg::point<i64>> ch;
ch.reserve((d_line.size() + u_line.size()) << 1);
ranges::move(d_line, back_inserter(ch));
ranges::move(u_line, back_inserter(ch));
int len_ch = static_cast<int>(ch.size());
i64 ans = 0;
{
cg::line<i64> l;
for (int i = 0, j = 0; i < len_ch; ++i) {
l = cg::line<i64>(ch[i], ch[(i + 1) % len_ch]);
while (cg::dist_point_line(ch[(j + 1) % len_ch], l) > cg::dist_point_line(ch[j], l)) {
j = (j + 1) % len_ch;
}
ckmax(ans, max(cg::dist_sqr(ch[j], ch[i]), cg::dist_sqr(ch[j], ch[(i + 1) % len_ch])));
}
}
cout << ans << '\n';
return 0;
}
回复
共 2 条回复,欢迎继续交流。
正在加载回复...