现在的位置: 首页 > 综合 > 正文

uva 11627 – Slalom(贪心+二分)

2014年10月02日 ⁄ 综合 ⁄ 共 1211字 ⁄ 字号 评论关闭

题目链接:uva 11627 - Slalom

题目大意:在一场滑雪比赛中要通过n个门,给出每个门的坐标(xi,yi)。数据给出w(每个门的宽度),v(水平方向上的最大速度,即x轴),以及n。然后是n行门的坐标。在给出m,表示有m双滑雪鞋,每双鞋的速度为s[i]。问说可以通过所有旗门的滑雪板的最大速度。


解题思路:首先现将s[i]排序,然后二分答案。判断只需要更具前后两个旗门的高度差来计算时间,由上一个可达区间推出下一个可达区间,然后加以判断。


#include <stdio.h>
#include <string.h>
#include <algorithm>

using namespace std;

const int N = 1000005;
const double eps = 1e-9;

struct state {
	int x, y;
}d[N];
int n, w, v, m, s[N];

inline void scan_d(int &ret) {  
	char c; ret = 0;  
	while((c = getchar()) < '0'|| c >'9');  
	while(c >= '0' && c <= '9') ret = ret * 10 + (c - '0'), c = getchar();  
}  

void init() {
	scanf("%d%d%d", &w, &v, &n);
	for (int i = 0; i < n; i++) scanf("%d%d", &d[i].x, &d[i].y);
	scanf("%d", &m);
	for (int i = 0; i < m; i++) scanf("%d", &s[i]);
	sort(s, s + m);
}

bool judge(int vh) {
	double l = d[n - 1].x, r = d[n - 1].x + w;

	for (int i = n - 2; i >= 0; i--) {
		int tmp = d[i + 1].y - d[i].y;
		double ti = (double)tmp / vh;

		l -= ti *  v; r += ti * v;	

		if (d[i].x + w < l) return false;
		if (d[i].x > r) return false;

		if (d[i].x - l > eps) l = d[i].x;
		if (d[i].x + w - r < eps) r = d[i].x + w;
	}
	return true;
}

bool solve() {
	if (!judge(s[0])) return false;
	if (judge(s[m - 1])) {
		printf("%d\n", s[m - 1]);
		return true;
	}

	int l = 0, r = m;

	while (true) {

		if (r - l == 1) break;

		int mid = (l + r) / 2;

		if (judge(s[mid])) l = mid;
		else r = mid;
	}
	printf("%d\n", s[l]);
	return true;;
}

int main () {
	int cas;
	scanf("%d", &cas);
	while (cas--) {
		init();
		if (solve() == false) printf("IMPOSSIBLE\n");
	}
	return 0;
}

抱歉!评论已关闭.