QOJ.ac

QOJ

IDProblemSubmitterResultTimeMemoryLanguageFile sizeSubmit timeJudge time
#616170#9434. Italian CuisineXiaoTieTL 0ms3816kbC++204.9kb2024-10-05 23:04:112024-10-05 23:04:11

Judging History

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

  • [2024-10-05 23:04:11]
  • 评测
  • 测评结果:TL
  • 用时:0ms
  • 内存:3816kb
  • [2024-10-05 23:04:11]
  • 提交

answer

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

using point_t = long long; // 全局数据类型,可修改为 long long 等

constexpr point_t eps = 1e-8;
constexpr long double PI = 3.1415926535897932384l;
point_t xc, yc, r;
// 点与向量
template <typename T>
struct point {
    T x, y;

    bool operator==(const point &a) const { return (abs(x - a.x) <= eps && abs(y - a.y) <= eps); }
    bool operator<(const point &a) const
    {
        if (abs(x - a.x) <= eps)
            return y < a.y - eps;
        return x < a.x - eps;
    }
    bool operator>(const point &a) const { return !(*this < a || *this == a); }
    point operator+(const point &a) const { return {x + a.x, y + a.y}; }
    point operator-(const point &a) const { return {x - a.x, y - a.y}; }
    point operator-() const { return {-x, -y}; }
    point operator*(const T k) const { return {k * x, k * y}; }
    point operator/(const T k) const { return {x / k, y / k}; }
    T operator*(const point &a) const { return x * a.x + y * a.y; } // 点积
    T operator^(const point &a) const { return x * a.y - y * a.x; } // 叉积,注意优先级
    int toleft(const point &a) const
    {
        const auto t = (*this) ^ a;
        return (t > eps) - (t < -eps);
    } // to-left 测试
    T len2() const { return (*this) * (*this); }                  // 向量长度的平方
    T dis2(const point &a) const { return (a - (*this)).len2(); } // 两点距离的平方

    // 涉及浮点数
    long double len() const { return sqrtl(len2()); }                                                                      // 向量长度
    long double dis(const point &a) const { return sqrtl(dis2(a)); }                                                       // 两点距离
    long double ang(const point &a) const { return acosl(max(-1.0l, min(1.0l, ((*this) * a) / (len() * a.len())))); }      // 向量夹角
    point rot(const long double rad) const { return {x * cos(rad) - y * sin(rad), x * sin(rad) + y * cos(rad)}; }          // 逆时针旋转(给定角度)
    point rot(const long double cosr, const long double sinr) const { return {x * cosr - y * sinr, x * sinr + y * cosr}; } // 逆时针旋转(给定角度的正弦与余弦)
};
using Point = point<point_t>;
Point o;
// 直线
template <typename T>
struct line {
    point<T> p, v; // p 为直线上一点,v 为方向向量

    bool operator==(const line &a) const { return v.toleft(a.v) == 0 && v.toleft(p - a.p) == 0; }
    int toleft(const point<T> &a) const { return v.toleft(a - p); } // to-left 测试

    // 涉及浮点数
    point<T> inter(const line &a) const { return p + v * ((a.v ^ (p - a.p)) / (v ^ a.v)); } // 直线交点
    long double dis(const point<T> &a) const { return abs(v ^ (a - p)) / v.len(); }         // 点到直线距离
    point<T> proj(const point<T> &a) const { return p + v * ((v * (a - p)) / (v * v)); }    // 点在直线上的投影
};

using Line = line<point_t>;
// 多边形
template <typename T>
struct polygon {
    vector<point<T>> p; // 以逆时针顺序存储

    size_t nxt(const size_t i) const { return i == p.size() - 1 ? 0 : i + 1; }
    size_t pre(const size_t i) const { return i == 0 ? p.size() - 1 : i - 1; }
};

using Polygon = polygon<point_t>;

// 凸多边形
template <typename T>
struct convex : polygon<T> {
    // 闵可夫斯基和

    // 旋转卡壳
    // func 为更新答案的函数,可以根据题目调整位置
    void rotcaliper(T &ans, T &res) const
    {
        const auto &p = this->p;
        const auto area = [](const point<T> &u, const point<T> &v, const point<T> &w) { return (w - u) ^ (w - v); };
        const int n = p.size();
        for (int i = 0, j = 1; i < n; i++) {
            while (1) {
                int nxtj = (j + 1) % n;
                Line x = {p[i], p[this->nxt(j)] - p[i]};
                if (x.dis({o.x, o.y}) <= r) {
                    break;
                }
                point_t cross = (p[j] - p[i]) ^ (p[nxtj] - p[i]);
                ans += abs(cross);
                j = nxtj;
            }
            res = max(res, ans);
            int nxti = (i + 1) % n;
            point_t cross = (p[j] - p[i]) ^ (p[nxti] - p[i]);
            ans -= abs(cross);
        }
    }

    // 题目要求的答案
    T get_area() const
    {
        const auto &p = this->p;
        T ans = 0;
        T res = 0;
        rotcaliper(ans, res);
        return res;
    }
};

using Convex = convex<point_t>;

void solve()
{
    int n;
    cin >> n;
    cin >> o.x >> o.y >> r;
    Convex t1;
    t1.p.resize(n);
    for (int i = 0; i < n; i++)
        cin >> t1.p[i].x >> t1.p[i].y;
    int ans = t1.get_area();
    cout << ans << endl;
}

signed main()
{
    ios::sync_with_stdio(false);
    cin.tie(0);
    cout.tie(0);
    int T = 1;
    cin >> T;
    while (T--)
        solve();
    return 0;
}

Details

Tip: Click on the bar to expand more detailed information

Test #1:

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

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: 3596kb

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
Time Limit Exceeded

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

result: