题解

2 条题解

  • 0
    @ 2025-12-22 10:17:27

    https://www.luogu.com.cn/problem/solution/P3829

    #include <algorithm>
    #include <cstdio>
    #include <cmath>
    #define eps 1e-12
    #define maxn 100010
    #define maxm 400010
    #define calc(a, b, c) (cross((b)-(a),(c)-(a)))
    using namespace std;
    const double PI = acos(-1);
    struct P{
        double x, y;
        P(double x = 0.0, double y = 0.0):x(x), y(y) {}
    }p[maxm];
    P operator + (P a, P b) {return (P){a.x + b.x, a.y + b.y};}
    P operator - (P a, P b) {return (P){a.x - b.x, a.y - b.y};}
    P operator - (P a) {return (P){-a.x, -a.y};}
    P operator * (P a, double b) {return (P){a.x * b, a.y * b};} // 数乘
    bool operator < (const P& a, const P& b) {
        return a.x==b.x?a.y<b.y:a.x<b.x;
    }
    double dot(P a, P b) {return a.x*b.x+a.y*b.y;} // 点积
    double cross(P a, P b) {return a.x*b.y-a.y*b.x;} // 叉积
    double abs(P a) {return sqrt(a.x*a.x+a.y*a.y);} // 取模
    P rotate(P a, double t) { // 旋转
        double c = cos(t), s = sin(t);
        return (P) {a.x*c-a.y*s, a.x*s+a.y*c};
    }
    int q[maxn];
    int main() {
        int n, c = 0;
        double a, b, r, x, y, t;
        scanf("%d%lf%lf%lf", &n, &b, &a, &r);
        a /= 2.0, b /= 2.0; // 取得半长和半宽
        for(int i = 1; i <= n; i++) {
            scanf("%lf%lf%lf", &x, &y, &t);
            x += eps, y += eps, t += eps; // 扰动,避免出现除0或者NaN
            P _ = (P){x, y}; // 中心
            p[++c] = rotate((P){a-r, b-r}, t) + _; // 先旋转再加中心
            p[++c] = rotate((P){r-a, b-r}, t) + _;
            p[++c] = rotate((P){r-a, r-b}, t) + _;
            p[++c] = rotate((P){a-r, r-b}, t) + _;
        }
        sort(p+1, p+c+1); // x-y 排序
        int T = 0;
        for(int i = 1; i <= c; i++) { // 下凸壳
            while(T>1&&calc(p[q[T-1]],p[q[T]],p[i])<=0)T--;
            q[++T] = i;
        }
        int tmp = T;
        for(int i = c - 1; i; i--) { // 上凸壳
            while(T>tmp&&calc(p[q[T-1]],p[q[T]],p[i])<=0)T--;
            q[++T] = i;
        }
        double ans = 2 * PI * r; // 加上一周
        for(int i = 1; i < T; i++) ans += abs(p[q[i]]-p[q[i+1]]);
        printf("%.2lf", ans);
        return 0;
    }
    
    
  • -4
    @ 2016-01-10 18:25:24

    虽然我没有AC但我来抢个沙发

  • 1

信息

ID
1855
难度
6
分类
(无)
标签
递交数
112
已通过
27
通过率
24%
被复制
2
上传者