QOJ.ac

QOJ

IDProblemSubmitterResultTimeMemoryLanguageFile sizeSubmit timeJudge time
#598629#9434. Italian Cuisineucup-team3584#WA 0ms3768kbC++204.3kb2024-09-28 22:41:042024-09-28 22:41:04

Judging History

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

  • [2024-09-28 22:41:04]
  • 评测
  • 测评结果:WA
  • 用时:0ms
  • 内存:3768kb
  • [2024-09-28 22:41:04]
  • 提交

answer

#pragma GCC optimize("Ofast")
#include <bits/stdc++.h>
using namespace std;
typedef long long int ll;
typedef unsigned long long int ull;

mt19937_64 rng(chrono::steady_clock::now().time_since_epoch().count());
ll myRand(ll B) { return (ull)rng() % B; }

// 整数幾何
typedef ll Integer;
const Integer eps = 0;
inline constexpr int sgn(Integer a, Integer b = 0) { return (a - b < -eps) ? -1 : (a - b > eps) ? 1 : 0; }
inline constexpr int arg_type(Integer x, Integer y) { return y < 0 ? 2 : x < 0 ? 1 : 0; }
struct Point {
    Integer x, y;
    constexpr Point(Integer x = 0, Integer y = 0) : x(x), y(y) {}
    constexpr Point operator+() const noexcept { return *this; }
    constexpr Point operator-() const noexcept { return Point(-x, -y); }
    constexpr Point operator+(const Point &p) const { return Point(x + p.x, y + p.y); }
    constexpr Point operator-(const Point &p) const { return Point(x - p.x, y - p.y); }
    constexpr Point &operator+=(const Point &p) { return x += p.x, y += p.y, *this; }
    constexpr Point &operator-=(const Point &p) { return x -= p.x, y -= p.y, *this; }
    constexpr Point &operator*=(const Integer &k) { return x *= k, y *= k, *this; }
    constexpr Point operator*(const Integer &k) { return Point(x * k, y * k); }
    constexpr bool operator==(const Point &r) const noexcept { return r.x == x and r.y == y; }
    constexpr Integer dot(const Point &r) const { return x * r.x + y * r.y; }
    constexpr Integer cross(const Point &r) const { return x * r.y - y * r.x; }
    constexpr Integer norm2() const { return x * x + y * y; }
    // 比較関数
    constexpr bool lex_comp(const Point &r) const { return sgn(x, r.x) < 0 || (sgn(x, r.x) == 0 and sgn(y, r.y) < 0); }
    constexpr bool arg_comp(const Point &r) const {
        int L = arg_type(x, y), R = arg_type(r.x, r.y);
        if (L != R) return L < R;
        Integer crs = (*this).cross(r);
        if (crs == 0) return abs(x) + abs(y) < abs(r.x) + abs(r.y);
        else return crs > 0;
    }
    // IO
    friend istream &operator>>(istream &is, Point &p) {
        is >> p.x >> p.y;
        return (is);
    }
    friend ostream &operator<<(ostream &os, Point &p) { return os << p.x << " " << p.y; }
};

Integer dot(Point a, Point b) { return a.dot(b); }
Integer cross(Point a, Point b) { return a.cross(b); }

bool is_in_triangle(vector<Point> v, Point p) {
    bool in = false;
    for (int i = 0; i < v.size(); ++i) {
        Point a = v[i], b = v[(i + 1) % v.size()];
        a -= p, b -= p;
        if (a.y > b.y) std::swap(a, b);
        if (sgn(a.y) <= 0 and 0 < sgn(b.y) and sgn(cross(a, b)) < 0) in ^= 1;
    }
    return in;
}

int main() {
    cin.tie(nullptr);
    ios::sync_with_stdio(false);
    int q;
    cin >> q;
    while (q--) {
        int n;
        cin >> n;
        Point r;
        ll rr;
        cin >> r >> rr;
        vector<Point> p(n);
        for (int i = 0; i < n; ++i) {
            cin >> p[i];
        }
        for (int i = 0; i < n; ++i) {
            p.push_back(p[i]);
        }
        for (int i = 0; i < n; ++i) {
            p.push_back(p[i]);
        }
        auto area = [&](Point a, Point b, Point c) -> ll {
            b -= a, c -= a;
            ll bx = b.x, by = b.y, cx = c.x, cy = c.y;
            return abs(bx * cy - cx * by);
        };

        ll res = 0, sum = 0;
        for (int i = 0, j = 0; i < n; ++i) {
            j = max(j, i + 2);
            while (j < p.size()) {
                vector<Point> vs = {p[i], p[j - 1], p[j]};
                if (is_in_triangle(vs, r)) break;
                double d = 1e18;
                auto dist = [&](Point a, Point b) -> double {
                    b -= a;
                    return sqrt(b.x * b.x + b.y * b.y);
                };
                d = min(d, dist(r, vs[0]));
                d = min(d, dist(r, vs[2]));
                d = min(d, abs(cross(r - vs[0], vs[2] - vs[0])) / (double)dist(vs[2], vs[0]));
                if (rr <= d) {
                    sum += area(p[i], p[j - 1], p[j]);
                    j += 1;
                } else {
                    break;
                }
            }
            res = max(res, sum);
            if (j > i + 2) {
                sum -= area(p[i], p[i + 1], p[j - 1]);
            }
        }
        cout << res << "\n";
    }
}

Details

Tip: Click on the bar to expand more detailed information

Test #1:

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

input:

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

output:

5
24
0

result:

ok 3 number(s): "5 24 0"

Test #2:

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

input:

1
6
0 0 499999993
197878055 -535013568
696616963 -535013568
696616963 40162440
696616963 499999993
-499999993 499999993
-499999993 -535013568

output:

286862654137719264

result:

wrong answer 1st numbers differ - expected: '0', found: '286862654137719264'