[ZJOI2008]瞭望塔

用每条相邻两点所构成的直线维护一个下凸。

主要注意凸包的点与地面的高度差,地面的拐点与凸包的高度差。

/**
 * Problem:[JLOI2013]Tower
 * Author:Shun Yao
 * Time:2013.5.30
 * Result:Accepted
 */

#include <cstring>
#include <cstdlib>
#include <cstdio>
#include <algorithm>

const long Maxn = 305;

double abs(double x) {
	return x < 0 ? -x : x;
}

long cmp(double x, double y) {
	if (abs(x - y) < 1e-8)
		return 0;
	if (x < y)
		return -1;
	return 1;
}

double min(double x, double y) {
	return x < y ? x : y;
}

class pnode {
public:
	double x, y;
	pnode() {}
	~pnode() {}
} p[Maxn];

class qnode {
public:
	double k, b, x;
	qnode() {}
	~qnode() {}
} q[Maxn], *ql, *qq;

bool cmpk(qnode x, qnode y) {
	return cmp(x.k, y.k) == 0 ? x.b > y.b : x.k < y.k;
}

bool cmpkk(qnode x, qnode y) {
	return cmp(x.k, y.k) == 0;
}

double cross(qnode x, qnode y) {
	return (x.b - y.b) / (y.k - x.k);
}

int main() {
	static long n, i, nn;
	static double ans;
	freopen("tower.in", "r", stdin);
	freopen("tower.out", "w", stdout);
	scanf("%ld", &n);
	for (i = 1; i <= n; ++i)
		scanf("%lf", &p[i].x);
	for (i = 1; i <= n; ++i)
		scanf("%lf", &p[i].y);
	for (i = 1; i < n; ++i) {
		q[i].k = (p[i].y - p[i + 1].y) / (p[i].x - p[i + 1].x);
		q[i].b = -q[i].k * p[i].x + p[i].y;
	}
	std::sort(ql = q + 1, q + n, cmpk);
	nn = std::unique(q + 1, q + n, cmpkk) - q;
	for (qq = ql + 1; qq != q + nn; ++qq) {
		while (ql > q + 1 && cmp(cross(*qq, *(ql - 1)), (*ql).x) <= 0)
			--ql;
		*(++ql) = *qq;
		(*ql).x = cross(*ql, *(ql - 1));
	}
	i = 1;
	ans = 1e20;
	for (qq = q + 1; qq != ql; ++qq) {
		while (i <= n && cmp(p[i].x, (*(qq + 1)).x) <= 0) {
			ans = min(ans, abs(p[i].x * (*qq).k + (*qq).b - p[i].y));
			++i;
		}
		if (i > n)
			break;
		if (i > 1)
			ans = min(ans, abs((*(qq + 1)).x * (*(qq + 1)).k + (*(qq + 1)).b - ((p[i].y - p[i - 1].y) / (p[i].x - p[i - 1].x) * ((*(qq + 1)).x - p[i].x) + p[i].y)));
	}
	while (i <= n) {
		ans = min(ans, abs(p[i].x * (*qq).k + (*qq).b - p[i].y));
		++i;
	}
	printf("%.3lf", ans);
	fclose(stdin);
	fclose(stdout);
	return 0;
}

 

posted @ 2013-06-03 14:56  hsuppr  阅读(310)  评论(0编辑  收藏  举报