mx求助凸包
查看原帖
mx求助凸包
267481
刘嘉琦楼主2022/6/19 18:29

大概率板子没问题

样例不过,在其他地方提交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;
} 
2022/6/19 18:29
加载中...