QOJ.ac

QOJ

IDProblemSubmitterResultTimeMemoryLanguageFile sizeSubmit timeJudge time
#579035#8550. All the Way Leftthinking (Fedor Romashov, Alexey Mikhnenko, Gimran Abdullin)WA 0ms3840kbC++202.9kb2024-09-21 05:37:492024-09-21 05:37:49

Judging History

This is the latest submission verdict.

  • [2024-09-21 05:37:49]
  • Judged
  • Verdict: WA
  • Time: 0ms
  • Memory: 3840kb
  • [2024-09-21 05:37:49]
  • Submitted

answer

#include <bits/stdc++.h>
using namespace std;

using ll = long long;
using ld = long double;

#define all(a) begin(a), end(a)
#define len(a) int((a).size())

struct point {
    ll x, y;

    ll length() const {
        return x * x + y * y;
    }

    point operator-(const point &other) const {
        return {x - other.x, y - other.y};
    }

    ll operator%(const point &other) const {
        return x * other.y - y * other.x;
    }
};

void solve(int /* test_num */) {
    int n;
    cin >> n;
    vector<point> a(n);
    for (auto &[x, y] : a) {
        cin >> x >> y;
    }
    if (n <= 2) {
        cout << n << '\n';
        return;
    }

    bool in_one_line = true;
    for (int i = 2; i < n; i++) {
        in_one_line &= (a[i] - a[0]) % (a[1] - a[0]) == 0;
    }
    if (in_one_line) {
        cout << "2\n";
        return;
    }

    for (int i = 1; i < n; i++) {
        if (make_pair(a[i].x, a[i].y) < make_pair(a[0].x, a[0].y)) {
            swap(a[i], a[0]);
        }
    }

    sort(1 + all(a), [&](point p, point q) {
        p = p - a[0];
        q = q - a[0];
        ll prod = p % q;
        if (prod != 0) {
            return prod > 0;
        }
        return p.length() < q.length();
    });

    vector<point> hull = {a[0], a[1]}, rem;
    for (int i = 2; i < n; i++) {
        while ((hull.back() - hull[len(hull) - 2]) % (a[i] - hull.back()) < 0) {
            rem.push_back(hull.back());
            hull.pop_back();
        }
        hull.push_back(a[i]);
    }

    map<pair<ll, ll>, int> mem;
    mt19937 rng(chrono::steady_clock::now().time_since_epoch().count());

    auto hash = [&](point p) {
        auto it = mem.find({p.x, p.y});
        if (it != mem.end()) {
            return it->second;
        }
        return mem[{p.x, p.y}] = rng();
    };

    auto solve = [&](point c) -> vector<int> {
        sort(all(rem), [&](point p, point q) {
            p = p - c;
            q = q - c;
            return p % q > 0;
        });

        vector<int> possible{0};
        possible.reserve(len(rem) + 1);
        int cur_hash = 0;
        for (int i = 0, j = 0; i < len(rem); i = j) {
            while (j < len(rem) && (rem[i] - c) % (rem[j] - c) == 0) {
                cur_hash ^= hash(rem[j++]);
            }
            possible.push_back(cur_hash);
        }
        return possible;
    };

    int ans = 0;
    for (int i = 0; i < len(hull); i++) {
        point a = hull[i], b = hull[(i + 1) % len(hull)];
        auto v = solve(a), u = solve(b);
        v.insert(v.end(), all(u));
        sort(all(v));
        ans += unique(all(v)) - v.begin();
    }
    cout << ans << '\n';
}

int main() {
    cin.tie(nullptr)->sync_with_stdio(false);

    int tests;
    cin >> tests;
    for (int test_num = 1; test_num <= tests; test_num++) {
        solve(test_num);
    }
}

Details

Tip: Click on the bar to expand more detailed information

Test #1:

score: 100
Accepted
time: 0ms
memory: 3540kb

input:

3
4
1 1
3 1
2 2
2 3
3
1 1
1 2
1 3
6
1 1
2 1
2 2
2 3
3 2
4 2

output:

6
2
13

result:

ok 3 number(s): "6 2 13"

Test #2:

score: -100
Wrong Answer
time: 0ms
memory: 3840kb

input:

15
1
1 1
2
1 1
1 2
3
1 1
1 2
1 3
3
1 1
1 2
2 2
5
1 1
1 3
2 2
3 1
3 3
6
1 1
1 3
2 2
3 2
4 1
4 3
6
1 3
2 1
2 2
2 3
2 4
3 2
6
1 1
5 1
3 5
2 2
4 2
3 3
7
1 1
5 1
2 2
3 2
4 2
3 3
3 4
6
2 10
8 9
2 3
2 5
3 5
2 6
10
1 10
7 6
8 4
3 8
6 9
3 7
6 8
8 5
10 9
8 8
8
1 1
2 3
2 4
1 6
5 3
5 4
6 1
6 6
8
1 1
2 3
3 3
4 2...

output:

1
2
2
3
8
14
12
14
18
13
43
30
22
10
14

result:

wrong answer 8th numbers differ - expected: '16', found: '14'