uva 11627 - Slalom(贪心+二分)

232 篇文章 0 订阅
179 篇文章 0 订阅

题目链接: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;
}


  • 1
    点赞
  • 0
    收藏
    觉得还不错? 一键收藏
  • 0
    评论

“相关推荐”对你有帮助么?

  • 非常没帮助
  • 没帮助
  • 一般
  • 有帮助
  • 非常有帮助
提交
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值