Problem E: Slalom

You may select from
You may start and finish at any two horizontal positions. Determine which pair of skis will allow you to get through the race course, passing through all the gates, in the shortest amount of time.
Input Specification
The first line of input contains a single integer, the number of test cases to follow.The first line of each test case contains the three integers
The following
The next line of the test case contains an integer
The following
Sample Input
2
3 2 3
1 1
5 2
1 3
3
3
2
1
3 2 3
1 1
5 2
1 3
1
3
Output Specification
Output one line for each test case. If it is impossible to complete the race with any pair of skis, print the lineOutput for Sample Input
2
IMPOSSIBLE
题意: 现在又n双滑雪板, 每双有一个速度Sj, 在滑雪比赛中, 通过n个障碍, 左右像个w距离, (xi, xi+w);
海拔yi, Sj是竖直方向速度, 并且有一个固定的水平速度vh, 要你选择出能通过全部障碍, 速度最大
的一双滑雪板.
解题思路:
1. 因为水平移动的速度vh是固定, 那么可以通过全部障碍而丢失一个, 显然当Sj越小时候越容易
完成比赛. 可以采用二分方法, 枚举出最优的竖直方向速度, 然后在给出的Sj中找出最接近的
一个即可.
代码:
#include <cstdio>
#include <iostream>
#include <cstring>
using namespace std;
#define MAX 100005
#define max(a,b) (a)>(b)?(a):(b)
#define min(a,b) (a)<(b)?(a):(b)
const int INF = (1<<28);
struct node
{
int x, y;
}a[MAX];
int w, vh, n;
int S;
bool judge(int v)
{
double x1 = a[0].x;
double x2 = a[0].x+w;
for(int i = 1; i < n; ++i)
{
double dist = vh * (double)(a[i].y-a[i-1].y)/(v*1.0);
x1 -= dist;
x2 += dist;
x1 = max(x1, (double)a[i].x);
x2 = min(x2, (double)(a[i].x)+w);
if(x1 > x2+1e-10) return false;
}
return true;
}
int main()
{
//freopen("input.txt", "r", stdin);
int caseNum;
scanf("%d", &caseNum);
while(caseNum--)
{
scanf("%d %d %d", &w, &vh, &n);
for(int i = 0; i < n; ++i)
scanf("%d %d", &a[i].x, &a[i].y);
int left = 0, right = INF, mid;
while(true)
{
mid = (left+right)/2;
if(left == mid) break;
if( judge(mid) ) left = mid;
else right = mid;
}
int result = 0, temp;
scanf("%d", &S);
for(int i = 0; i < S; ++i)
{
scanf("%d", &temp);
if(temp <= mid)
result = max(result, temp);
}
if(result == 0) printf("IMPOSSIBLE\n");
else printf("%d\n", result);
}
return 0;
}