QOJ.ac

QOJ

ID提交记录ID题目HackerOwner结果提交时间测评时间
#1083#688242#9520. Concave HullstavagestavageSuccess!2024-10-30 01:29:402024-10-30 01:29:42

详细

Extra Test:

Time Limit Exceeded

input:

1
7
-12 -7
10 -3
-15 -12
-12 -15
-2 12
-10 -9
8 3

output:


result:


ID题目提交者结果用时内存语言文件大小提交时间测评时间
#688242#9520. Concave HullstavageTL 56ms9984kbC++202.6kb2024-10-30 01:27:242024-10-30 01:36:27

answer

#include <bits/stdc++.h>
using namespace std;
typedef long long ll;
template<typename T>
struct Point {
  T x, y;
  bool operator<(Point p) const
  {
      if (x != p.x) return x < p.x;
      return y < p.y;
  }
  Point operator+(Point p) const { return {x + p.x, y + p.y}; }
  Point operator-(Point p) const { return {x - p.x, y - p.y}; }
  bool operator==(Point p) const { return x == p.x && y == p.y; }
  T det(Point rhs) { return x * rhs.y - y * rhs.x; }
};
using P = Point<ll>;
vector<P> GrahamScan(vector<P> &p)
{
    sort(p.begin(), p.end());
    int n = p.size(), m = 0;
    vector<P> res(n + 1);

    for (int i = 0; i < n; i++) {
        while (m > 1 && !((res[m - 1] - res[m - 2]).det(p[i] - res[m - 2]) > 0)) m--;
        res[m++] = p[i];
    }
    int kk = m;
    for (int i = n - 2; i >= 0; i--) {
        while (m > kk && !((res[m - 1] - res[m - 2]).det(p[i] - res[m - 2]) > 0)) m--;
        res[m++] = p[i];
    }

    if (n > 1) m--;
    res.erase(res.begin() + m, res.end());
    vector<P> tmp1 = res;
    sort(tmp1.begin(), tmp1.end());

    int j = 0;
    vector<P> tmp;
    for (int i = 0; i < n && j < tmp1.size(); i++) {
        if (p[i] == tmp1[j]) j++;
        else tmp.push_back(p[i]);
    }
    p = tmp;
    return res;
}
ll PolyArea2(vector<P> &p)
{
    int n = p.size();
    ll s = 0;
    for (int i = 1; i < n - 1; i++) {
        s += (p[i] - p[0]).det(p[i + 1] - p[0]);
    }
    return s;
}
void solve()
{
    int n;
    cin >> n;
    vector<P> a(n);
    for (int i = 0; i < n; i++) {
        cin >> a[i].x >> a[i].y;
    }
    vector<P> border = GrahamScan(a);
    vector<P> core = GrahamScan(a);
    if (core.size() == 0) {
        cout << -1 << "\n";
        return;
    }
    ll s = PolyArea2(border);
    int m1 = border.size(), m2 = core.size();
    int st = 0;
    ll mins = s;
    for (int i = 0; i < m2; i++) {
        ll tmps = (border[m1 - 1] - core[i]).det(border[0] - core[i]);
        if (mins > tmps) {
            mins = tmps;
            st = i;
        }
    }
    ll res = s - mins;
    int nex = (st + 1) % m2;
    for (int i = 0; i < m1 - 1; i++) {
        mins = (border[i] - core[st]).det(border[i + 1] - core[st]);
        while (nex != st) {
            ll tmp = (border[i] - core[nex]).det(border[i + 1] - core[nex]);
            if (mins >= tmp) mins = tmp, st = nex, nex = (nex + 1) % m2;
            else break;
        }
        res = max(res, s - mins);
    }
    cout << res << "\n";
}
int main()
{
    cin.tie(nullptr)->ios::sync_with_stdio(false);
    int t;
    cin >> t;
    while (t--) solve();
}