2 条题解
-
0
搬运工 (syrth0p1) LV 10 @ 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
- 上传者