题意描述比较恶心,首先需要明确题目给出的坐标描述的不是类似横版游戏的纵切图,实际上把整个斜面当做一个平面,详细说明见图,N个宽度为W的”门“, 横向移动的速度不能超过vh, S个速度为v[i]的滑雪板,滑雪板的速度是纵向移动的速度,完成比赛必须通过所有的门,求能够完成比赛的速度最快滑雪板的速度
#include <iostream>
#include <cstdio>
#include <cstdlib>
#include <cmath>
#include <queue>
#include <algorithm>
#include <vector>
#include <cstring>
#include <stack>
#include <cctype>
#include <utility>
#include <map>
#include <string>
#include <climits>
#include <set>
#include <string>
#include <sstream>
#include <utility>
#include <ctime>
using std::priority_queue;
using std::vector;
using std::swap;
using std::stack;
using std::sort;
using std::max;
using std::min;
using std::pair;
using std::map;
using std::string;
using std::cin;
using std::cout;
using std::set;
using std::queue;
using std::string;
using std::istringstream;
using std::make_pair;
using std::greater;
const int MAXN(100010);
int x[MAXN], y[MAXN];
int v[1000010];
bool legal(int goal, int W, int vh, int N)
{
double x1 = x[0], x2 = x[0]+W;
for(int i = 1; i < N; ++i)
{
double excur = double(y[i]-y[i-1])/goal*vh;
x1 -= excur;
x2 += excur;
if(x[i] > x2 || x[i]+W < x1)
return false;
x1 = max(x1, double(x[i]));
x2 = min(x2, double(x[i]+W));
}
return true;
}
int main()
{
int T;
scanf("%d", &T);
while(T--)
{
int W, vh, N;
scanf("%d%d%d", &W, &vh, &N);
for(int i = 0; i < N; ++i)
scanf("%d%d", x+i, y+i);
int S;
scanf("%d", &S);
for(int i = 0; i < S; ++i)
scanf("%d", v+i);
sort(v, v+S);
int l = 0, r = S;
while(l < r)
{
int m = (l+r) >> 1;
if(legal(v[m], W, vh, N))
l = m+1;
else
r = m;
}
if(l)
printf("%d\n", v[l-1]);
else
printf("IMPOSSIBLE\n");
}
return 0;
}