题意
在一场滑雪比赛中要通过n个门,给出每个门的坐标(xi,yi)。数据给出w(每个门的宽度),v(水平方向上的最大速度),以及n。
然后是n行门的坐标。在给出m,表示有m双滑雪鞋,每双鞋的速度为s[i]。
问:可以通过所有旗门的滑雪板的最大速度。
解析
首先现将s[i]排序,然后二分答案。判断只需要更具前后两个旗门的高度差来计算时间,由上一个可达区间推出下一个可达区间,然后判断上一个区间和下一个区间是否有交集,如果为空集,则无解。
#include <bits/stdc++.h>
using namespace std;
typedef long long ll;
const int INF = 0x3f3f3f3f;
const int N = 100005;
const int maxs = 1e6+5;
const double eps = 1e-10;
int w, vx, n, m;
int s[N*10];
struct Point {
double x, y;
} poi[N];
bool judge(int vy) {
double lt = poi[0].x, rt = poi[0].x + w;
for(int i = 1; i < n; i++) {
double dist = (double)(poi[i].y - poi[i-1].y) / vy * vx;
lt -= dist;
rt += dist;
lt = max(lt, (double)poi[i].x);
rt = min(rt, (double)poi[i].x + w);
if(lt > rt) return false;
}
return true;
}
int work() {
int L = 0, R = m-1, ret = -1;
while(L <= R) {
int M = (L+R)>>1;
if( judge(s[M]) ) {
ret = max(ret, s[M]);
L = M+1;
}else {
R = M-1;
}
}
return ret;
}
int main() {
int T;
scanf("%d", &T);
while(T--) {
scanf("%d%d%d", &w, &vx, &n);
for(int i = 0; i < n; i++) {
scanf("%lf%lf", &poi[i].x, &poi[i].y);
}
scanf("%d", &m);
for(int i = 0; i < m; i++) {
scanf("%d", &s[i]);
}
sort(s, s+m);
int ans = work();
if(ans == -1) puts("IMPOSSIBLE");
else printf("%d\n", ans);
}
return 0;
}