大概率板子没问题
样例不过,在其他地方提交WA掉30分,错的点与答案只差一点,所以怀疑问题与精度有关
#include <cstdio>
#include <algorithm>
#include <cmath>
const int N = 40005;
struct Point {
double x, y;
friend Point operator-(Point a, Point b) {
return Point{a.x - b.x, a.y - b.y};
}
friend double cmpk(Point a, Point b) {
return a.x * b.y - a.y * b.x;
}
friend double dis(Point a, Point b) {
return sqrt((a.x - b.x) * (a.x - b.x) + (a.y - b.y) * (a.y - b.y));
}
friend bool operator<(Point a, Point b) {
return cmpk(a, b) == 0 ? dis(a, Point{0, 0}) < dis(b, Point{0, 0}) : cmpk(a, b) > 0;
}
} p[N], st[N];
int n, cnt = 0, top = 0;
double a, b, r;
int main()
{
scanf("%d %lf %lf %lf", &n, &a, &b, &r);
double x, y, theta;
for (int i = 1; i <= n; i++, cnt += 3) {
scanf("%lf %lf %lf", &x, &y, &theta);
p[++cnt] = {x + cos(atan(a / b) - theta) * (sqrt(a * a + b * b) / 2 - r),
y - sin(atan(a / b) - theta) * (sqrt(a * a + b * b) / 2 - r)};
p[cnt + 1] = {p[cnt].x - sin(theta) * (a - 2 * r), p[cnt].y + cos(theta) * (a - 2 * r)};
p[cnt + 2] = {p[cnt + 1].x - cos(theta) * (b - 2 * r), p[cnt + 1].y - sin(theta) * (b - 2 * r)};
p[cnt + 3] = {p[cnt + 2].x + sin(theta) * (a - 2 * r), p[cnt + 2].y - cos(theta) * (a - 2 * r)};
}
n = cnt;
int t = -1;
for (int i = 1; i <= n; i++)
if (t == -1 || p[i].y < p[t].y || (p[i].y == p[t].y && p[i].x < p[t].x))
t = i;
std::swap(p[1], p[t]);
for (int i = 2; i <= n; i++)
p[i] = p[i] - p[1];
p[1] = Point{0, 0};
std::sort(p + 2, p + n + 1);
st[++top] = p[1];
for (int i = 2; i <= n; i++) {
while (top > 1 && cmpk(p[i] - st[top], st[top] - st[top - 1]) > 0)
top--;
st[++top] = p[i];
}
st[top + 1] = p[1];
double ans = 2 * 3.141592653589793 * r;
for (int i = 1; i <= top; i++)
ans += dis(st[i], st[i + 1]);
printf("%.2lf\n", ans);
return 0;
}