QOJ.ac

QOJ

IDProblemSubmitterResultTimeMemoryLanguageFile sizeSubmit timeJudge time
#598539#9434. Italian Cuisineucup-team3584#WA 56ms3852kbC++207.3kb2024-09-28 22:20:352024-09-28 22:20:36

Judging History

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

  • [2024-09-28 22:20:36]
  • 评测
  • 测评结果:WA
  • 用时:56ms
  • 内存:3852kb
  • [2024-09-28 22:20:35]
  • 提交

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; }

// https://onlinejudge.u-aizu.ac.jp/courses/library/4/CGL/all
////////////////////////////////////////////////////////////////////////////////
typedef long double Real;
const Real eps = 1e-7; // 1000 : 10^-8, 10000 : 10^-7
inline int sgn(Real a, Real b = 0) { return (a - b < -eps) ? -1 : (a - b > eps) ? 1 : 0; }
inline Real _sqrt(Real a) { return sqrt(max(a, (Real)0)); }
struct Point {
    Real x, y;
    Point() {}
    Point(Real x, Real y) : x(x), y(y) {}
    Point &operator-=(const Point &p) {
        x -= p.x;
        y -= p.y;
        return *this;
    }
    Point &operator+=(const Point &p) {
        x += p.x;
        y += p.y;
        return *this;
    }
    Point &operator*=(Real d) {
        x *= d;
        y *= d;
        return *this;
    }
    Point &operator/=(Real d) {
        x /= d;
        y /= d;
        return *this;
    }
    Point operator+(const Point &p) const {
        Point res(*this);
        return res += p;
    }
    Point operator-(const Point &p) const {
        Point res(*this);
        return res -= p;
    }
    Point operator*(Real d) const {
        Point res(*this);
        return res *= d;
    }
    Point operator/(Real d) const {
        Point res(*this);
        return res /= d;
    }
    bool operator<(const Point &p) const { return (sgn(x, p.x) < 0 or (sgn(x, p.x) == 0 and sgn(y, p.y) < 0)); }
    bool operator==(const Point &p) const { return (sgn(x - p.x) == 0 and sgn(y - p.y) == 0); }
    friend istream &operator>>(istream &is, Point &p) {
        is >> p.x >> p.y;
        return (is);
    }
    Real norm() { return _sqrt(x * x + y * y); }
    Real norm2() { return (x * x + y * y); }
    Point vec() { return (*this); }
    Point unit() { return (*this) / this->norm(); } // 単位ベクトル
    Point rotate(Real theta) { return {x * cos(theta) - y * sin(theta), x * sin(theta) + y * cos(theta)}; }
    Point perpendicular() { return {-y, x}; }
    Point normal() { return perpendicular().unit(); } // 法線ベクトル
};

Point vec(Point a, Point b) { return (b - a); }
Real dist(Point a, Point b) { return vec(a, b).norm(); }
Real dot(Point a, Point b) { return a.x * b.x + a.y * b.y; }
Real cross(Point a, Point b) { return a.x * b.y - a.y * b.x; }

// 線分
struct Segment : array<Point, 2> {
    Segment() {}
    Segment(Point a, Point b) { at(0) = a, at(1) = b; }
    Point vec() { return (at(1) - at(0)); }
    Real length() { return vec().norm(); }
    friend istream &operator>>(istream &is, Segment &s) {
        is >> s[0] >> s[1];
        return (is);
    }
};
// 直線
struct Line : Segment {
    Line() {}
    Line(Point a, Point b) : Segment(a, b) {}
    Line(Segment s) : Line(s[0], s[1]) {}
};

int ccw(Point a, Point b, Point c) {
    b -= a, c -= a;
    if (sgn(cross(b, c)) == 1) return 1;          // a,b,c 反時計回り
    if (sgn(cross(b, c)) == -1) return -1;        // a,b,c 時計周り
    if (sgn(dot(b, c)) == -1) return 2;           // c,a,b 一直線上
    if (sgn(c.norm() - b.norm()) == 1) return -2; // a,b,c 一直線上
    return 0;                                     // a,c,b 一直線上
}

// 垂直判定
template <typename T> bool is_orthogonal(T s, T t) { return sgn(dot(s.vec(), t.vec())) == 0; }
// 並行判定
template <typename T> bool is_parallel(T s, T t) { return sgn(cross(s.vec(), t.vec())) == 0; }
// 同一直線判定
template <typename T> bool is_same_line(T s, T t) { return abs(ccw(s[0], s[1], t[0])) != 1 and abs(ccw(s[0], s[1], t[1])) != 1; }
// 線分上の点判定
bool is_on_segment(Point p, Segment l) { return ccw(l[0], l[1], p) == 0; }
// 線分の交差判定(AOJ-2172)
bool is_intersect(Segment s, Segment t) {
    return ccw(s[0], s[1], t[0]) * ccw(s[0], s[1], t[1]) <= 0 and ccw(t[0], t[1], s[0]) * ccw(t[0], t[1], s[1]) <= 0;
}
// 2直線の交点(AOJ-2596)
pair<bool, Point> line_intersection(Line s, Line t) {
    if (is_same_line(s, t)) return {true, s[0]};
    else if (is_parallel(s, t)) return {false, Point()};
    else return {true, s[0] + s.vec() * cross(t[0] - s[0], t.vec()) / cross(s.vec(), t.vec())};
}
// 2線分の交点
pair<bool, Point> segment_intersection(Segment s, Segment t) {
    if (is_same_line(s, t)) {
        if (is_on_segment(s[0], t)) return {true, s[0]};
        else if (is_on_segment(s[1], t)) return {true, s[1]};
        else if (is_on_segment(t[0], s)) return {true, t[0]};
        else return {false, Point()};
    }
    if (!is_intersect(s, t)) return {false, Point()};
    else return line_intersection(Line(s), Line(t));
}
// 点と直線の距離
Real point_line_distance(Point p, Line l) { return abs(cross(p - l[0], l.vec())) / l.length(); }
// 点と線分の距離
Real point_segment_distance(Point p, Segment l) {
    if (sgn(dot(p - l[0], l.vec())) == -1) return dist(p, l[0]);
    else if (sgn(dot(p - l[1], l.vec())) == 1) return dist(p, l[1]);
    else return point_line_distance(p, l);
}
// 線分と線分の距離(AOJ-1157)
Real segment_segment_distance(Segment s, Segment t) {
    if (is_intersect(s, t)) return 0;
    Real res = point_segment_distance(s[0], t);
    res = min(res, point_segment_distance(s[1], t));
    res = min(res, point_segment_distance(t[0], s));
    res = min(res, point_segment_distance(t[1], s));
    return res;
}

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()];
        if (is_on_segment(p, Line(a, b))) {
            return true;
        }
        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]);
        }

        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;
                Real d = point_segment_distance(r, Segment(vs[0], vs[2]));
                if (sgn(rr, d) == -1) {
                    vs[1] -= vs[0], vs[2] -= vs[0];
                    sum += abs(vs[1].y * vs[2].x - vs[1].x * vs[2].y);
                    j += 1;
                } else {
                    break;
                }
            }
            res = max(res, sum);
            if (j > i + 2) {
                vector<Point> vs = {p[i], p[i + 1], p[j - 1]};
                vs[1] -= vs[0], vs[2] -= vs[0];
                sum -= abs(vs[1].y * vs[2].x - vs[1].x * vs[2].y);
            }
        }
        cout << res << "\n";
    }
}

Details

Tip: Click on the bar to expand more detailed information

Test #1:

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

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: 0
Accepted
time: 0ms
memory: 3776kb

input:

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

output:

0

result:

ok 1 number(s): "0"

Test #3:

score: -100
Wrong Answer
time: 56ms
memory: 3852kb

input:

6666
19
-142 -128 26
-172 -74
-188 -86
-199 -157
-200 -172
-199 -186
-195 -200
-175 -197
-161 -188
-144 -177
-127 -162
-107 -144
-90 -126
-87 -116
-86 -104
-89 -97
-108 -86
-125 -80
-142 -74
-162 -72
16
-161 -161 17
-165 -190
-157 -196
-154 -197
-144 -200
-132 -200
-128 -191
-120 -172
-123 -163
-138...

output:

5093
2862
2539
668
3535
7421
4883
5711
5624
1034
2479
3920
4372
2044
4996
5070
2251
4382
4175
1489
1154
3231
4038
1631
5086
14444
1692
6066
687
1512
4849
5456
2757
8341
8557
8235
1013
5203
10853
6042
6300
4480
2303
2728
1739
2187
3385
4266
6322
909
4334
1518
948
5036
1449
2376
3180
4810
1443
1786
47...

result:

wrong answer 2nd numbers differ - expected: '3086', found: '2862'