QOJ.ac

QOJ

ID题目提交者结果用时内存语言文件大小提交时间测评时间
#301006#3139. Largest QuadrilateralLCX756AC ✓4ms8608kbC++204.5kb2024-01-09 10:58:352024-01-09 10:58:35

Judging History

你现在查看的是最新测评结果

  • [2024-01-09 10:58:35]
  • 评测
  • 测评结果:AC
  • 用时:4ms
  • 内存:8608kb
  • [2024-01-09 10:58:35]
  • 提交

answer

#include <bits/stdc++.h>
using namespace std;
typedef long long ll;
typedef double db;
typedef pair <int, int> pii;
typedef pair <ll, ll> pll;
#define fir first
#define sec second
typedef vector <int> vi;
typedef vector <ll> vl;

#ifdef LCX
#define msg(args...) fprintf(stderr, args)
#else
#define msg(...) void()
#endif

int sgn(const ll &x) {
    if (x == 0) return 0;
    return x > 0 ? 1 : -1;
}

struct Point {
    ll x, y;
    Point() : x(0), y(0) {}
    template <typename __Tp1, typename __Tp2>
    Point(__Tp1 x, __Tp2 y) : x(x), y(y) {}

    Point operator + (const Point &p) const { return Point(x + p.x, y + p.y); }
    Point operator - () const { return Point(-x, -y); }
    Point operator - (const Point &p) const { return Point(x - p.x, y - p.y); }
    Point operator * (const db &k) const { return Point(x * k, y * k); }
    Point operator / (const db &k) const { return Point(x / k, y / k); }

    bool operator < (const Point &p) const {
        if (sgn(x - p.x) != 0)
            return sgn(x - p.x) < 0;
        return sgn(y - p.y) < 0;
    }
    bool operator > (const Point &p) const {
        if (sgn(x - p.x) != 0)
            return sgn(x - p.x) > 0;
        return sgn(y - p.y) > 0;
    }
    bool operator <= (const Point &p) const {
        if (sgn(x - p.x) != 0)
            return sgn(x - p.x) < 0;
        return sgn(y - p.y) <= 0;
    }
    bool operator >= (const Point &p) const {
        if (sgn(x - p.x) != 0)
            return sgn(x - p.x) > 0;
        return sgn(y - p.y) >= 0;
    }
    bool operator == (const Point &p) const {
        return sgn(x - p.x) == 0 && sgn(y - p.y) == 0;
    }
    bool operator != (const Point &p) const {
        return sgn(x - p.x) != 0 || sgn(y - p.y) != 0;
    }
};
ll cross(const Point &p, const Point &q) { return p.x * q.y - p.y * q.x; }

struct Line {
    Point a, v;
    #ifdef RESTORE_ANGLE_IN_STRUCTURE
    db ang;
    #endif
    Line() : a(), v() {
        #ifdef RESTORE_ANGLE_IN_STRUCTURE
        ang = 0;
        #endif
    }
    Line(const Point &a, const Point &v) : a(a), v(v) {
        #ifdef RESTORE_ANGLE_IN_STRUCTURE
        ang = angle(v);
        #endif
    }
};
Line toLine(const Point &s, const Point &e) { return Line(s, e - s); }
int side(const Point &p, const Line &l) { return sgn(cross(l.v, p - l.a)); }
// p is on the left (counterclockwise) side of l if side(p, l) == 1

namespace Convex {
const int maxn = 1e5 + 10;
Point tmp[maxn];
int tot;
int build(Point *a, int &n) {
    sort(a + 1, a + n + 1);
    n = unique(a + 1, a + n + 1) - a - 1;
    if (n <= 2) return n;
    tmp[tot = 1] = a[1];
    for (int i = 2; i <= n; ++i) {
        while (tot > 1 && side(a[i], toLine(tmp[tot - 1], tmp[tot])) <= 0) --tot;
        tmp[++tot] = a[i];
    }
    int lim = tot;
    for (int i = n - 1; i >= 1; --i) {
        while (tot > lim && side(a[i], toLine(tmp[tot - 1], tmp[tot])) <= 0) --tot;
        tmp[++tot] = a[i];
    }
    n = tot - 1;
    for (int i = 1; i <= tot; ++i) a[i] = tmp[i];
    return lim;
}
// return the index of the upper right corner
}

const int maxn = 1e5 + 10;
int n;
Point a[maxn], tmp[maxn];
void go(int &p, const Point &v) {
    while (side(a[p + 1], Line(a[p], v)) < 0 ||
            side(a[p - 1], Line(a[p], v)) < 0) p = p % n + 1;
}
void work() {
    scanf("%d", &n);
    for (int i = 1; i <= n; ++i)
        scanf("%lld%lld", &a[i].x, &a[i].y),
        tmp[i] = a[i];
    int nn = n;
    Convex::build(a, n);
    a[n + 1] = a[1], a[0] = a[n];
    if (n <= 2) return printf("0\n"), void();
    ll ans = 0;
    if (n == 3) {
        bool vis[4] = {0, 0, 0, 0};
        ll all = cross(a[2] - a[1], a[3] - a[1]);
        for (int i = 1; i <= nn; ++i) {
            int flg = 0;
            for (int j = 1; j <= 3; ++j)
                if (!vis[j] && a[j] == tmp[i]) flg = 1, vis[j] = 1;
            if (!flg) {
                for (int j = 1; j <= 3; ++j)
                    ans = max(ans, all - cross(a[j] - tmp[i], a[j + 1] - tmp[i]));
            }
        }
    }
    else {
        for (int i = 1, j = 1, k = 1, l = 1; i <= n; ++i) {
            go(j, a[i] - a[i + 1]);
            go(k, a[j] - a[i]);
            go(l, a[i] - a[j]);
            ans = max(ans, cross(a[k] - a[i], a[j] - a[i]) +
                cross(a[j] - a[i], a[l] - a[i]));
        }
    }
    if (ans & 1) printf("%lld.5\n", ans / 2);
    else printf("%lld\n", ans / 2);
}

int main() {
    int T; scanf("%d", &T);
    while (T --> 0) work();
    return 0;
}

详细

Test #1:

score: 100
Accepted
time: 1ms
memory: 8588kb

input:

3
5
0 0
1 0
3 1
1 2
0 1
4
0 0
4 0
0 4
1 1
4
0 0
1 1
2 2
1 1

output:

3
6
0

result:

ok 3 lines

Test #2:

score: 0
Accepted
time: 1ms
memory: 8592kb

input:

1
4
0 0
1 0
0 1
3 2

output:

2.5

result:

ok single line: '2.5'

Test #3:

score: 0
Accepted
time: 1ms
memory: 8508kb

input:

3
4
0 0
0 0
0 0
0 0
5
0 0
1 0
3 1
1 2
0 1
4
0 0
4 0
0 4
1 1

output:

0
3
6

result:

ok 3 lines

Test #4:

score: 0
Accepted
time: 0ms
memory: 8608kb

input:

3
4
0 0
1 1
2 2
1 1
5
0 0
3 3
1 1
4 4
2 2
6
0 0
0 4
4 0
0 0
1 1
1 2

output:

0
0
8

result:

ok 3 lines

Test #5:

score: 0
Accepted
time: 2ms
memory: 8432kb

input:

3
6
0 0
8 8
7 9
6 9
5 8
0 99
29
999891293 708205
369022896 771
993004062 999827531
929592437 29458
994968624 999539287
569046020 1943
2200 986643253
11189 5792636
712825 999917190
2482686 272282
43058 665660
10373878 31825
508452623 112
3304 269412577
43817590 3789
999996618 957802194
999902626 9749...

output:

388
996775018731291724.5
965005706567704502.5

result:

ok 3 lines

Test #6:

score: 0
Accepted
time: 4ms
memory: 8592kb

input:

3
4096
53819837 441491349
842988334 208694314
834815184 199336081
754579314 871065186
798603871 163346278
881287987 261003199
69176974 629967383
167500703 196776949
934427498 382642646
949669136 517253054
205028216 839840619
904403509 697377307
909983630 685508552
106436006 718191161
704172704 90101...

output:

405000001187842381
405000001187842381
405000001187842381

result:

ok 3 lines