题意描述比较恶心,首先需要明确题目给出的坐标描述的不是类似横版游戏的纵切图,实际上把整个斜面当做一个平面,详细说明见图,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; }