QOJ.ac
QOJ
ID | Problem | Submitter | Result | Time | Memory | Language | File size | Submit time | Judge time |
---|---|---|---|---|---|---|---|---|---|
#735948 | #9520. Concave Hull | PHarr | RE | 0ms | 0kb | C++20 | 3.0kb | 2024-11-11 23:01:44 | 2024-11-11 23:01:45 |
answer
#include <bits/stdc++.h>
using i32 = int32_t;
using i64 = long long;
#define int i64
const int inf = LLONG_MAX / 2;
struct Point {
i64 x, y;
Point(i64 x = 0, i64 y = 0) : x(x), y(y) {};
};
const Point O(0, 0);
using Vec = Point;
using Points = std::vector<Point>;
Vec operator-(Vec u, Vec v) { return Vec(u.x - v.x, u.y - v.y); }
int operator^(Vec u, Vec v) { return u.x * v.y - u.y * v.x; }
bool operator<(Point A, Point B) {
if (A.x != B.x) return A.x < B.x;
return A.y < B.y;
}
bool check(Point p, Point q, Point r) {
return 0 < ((q - p) ^ (r - q));
}
std::pair<Points, Points> chull(Points &ps) {
std::sort(ps.begin(), ps.end());
std::vector<int> I{0}, used(ps.size());
for (int i = 1; i < ps.size(); i++) {
while (I.size() > 1 and !check(ps[I[I.size() - 2]], ps[I.back()], ps[i]))
used[I.back()] = 0, I.pop_back();
used[i] = 1, I.push_back(i);
}
for (int i = ps.size() - 2, tmp = I.size(); i >= 0; i--) {
if (used[i]) continue;
while (I.size() > tmp and !check(ps[I[I.size() - 2]], ps[I.back()], ps[i]))
used[I.back()] = 0, I.pop_back();
used[i] = 1, I.push_back(i);
}
Points H;
I.pop_back();
for (auto i: I)
H.push_back(ps[i]), assert(used[i] == 0);
Points notH;
for (int i = 1; i < ps.size(); i++) {
if (used[i]) continue;
notH.push_back(ps[i]);
}
return std::pair(H, notH);
}
int area(Point a, Point b, Point c) {
return abs((b - a) ^ (c - a));
}
void solve() {
int n;
std::cin >> n;
Points ps(n);
for (auto &[x, y]: ps)
std::cin >> x >> y;
auto [c1, new_ps] = chull(ps);
ps = move(new_ps);
int chull_area = 0;
for (int i = 0; i < c1.size(); i++)
chull_area += c1[i] ^ c1[(i + 1) % c1.size()];
if (ps.empty()) {
std::cout << -1 << "\n";
} else if (ps.size() < 3) {
int ret = inf;
for (int i = 0; i < ps.size(); i++)
for (int j = 0; j < c1.size(); j++)
ret = std::min(ret, area(ps[i], c1[j], c1[(j + 1) % c1.size()]));
std::cout << chull_area - ret << "\n";
} else {
auto [c2, _] = chull(ps);
int it = 0, val = area(c1[0], c1[1], c2[0]);
for (int i = 1, x; i < c1.size(); i++) {
x = abs((c1[i] - c2[0]) ^ (c1[(i + 1) % c1.size()] - c2[0]));
if (x < val) val = x, it = i;
}
int ret = val;
for (int i = 1; i < c2.size(); i++) {
val = area(c2[i], c1[it], c1[(it + 1) % c1.size()]);
for (int x; true; it = (it + 1) % c1.size()) {
x = area(c2[i], c1[(it + 1) % c1.size()], c1[(it + 2) % c1.size()]);
if (x > val) break;
val = x;
}
ret = std::min(ret, val);
}
std::cout << chull_area - ret << "\n";
}
return;
}
i32 main() {
i32 T;
std::cin >> T;
while (T--)
solve();
return 0;
}
Details
Tip: Click on the bar to expand more detailed information
Test #1:
score: 0
Runtime Error
input:
2 6 -2 0 1 -2 5 2 0 4 1 2 3 1 4 0 0 1 0 0 1 1 1