赞
踩
You may select from S pairs of skis, where the jth pair has speedsj.Your movement is governed by the following rule: if you select a pair of skiswith speed sj, you move with a constant downward velocity of sjmetres per second.Additionally, at any time you may move at a horizontal speed of at most vhmetres per second.
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.
The first line of each test case contains the three integers W, vh, andN, separated by spaces, with1 <= W <= 108,1 <= vh <= 106, and1 <= N <= 105.
The following N lines of the test case each contain two integers xiandyi, the horizontal and vertical positions respectively of theith left gate, with1 <= xi, yi <= 108.
The next line of the test case contains an integer S, the number of skis,with1 <= S <= 106.
The following S lines of the test case each contain one integer sj, thespeed of the jth pair of skis, with 1 <= sj <= 106.
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
2 IMPOSSIBLE
解题报告: 首先,题意比较难懂。简单来说就是下面这个样子:
图很烂……黑色的线条代表gate,左边的点的坐标就是(xi, yi)。人从山上y=0的地方滑下来,垂直速度为sj, 水平速度为0 - vh。
题目让我们求出可以通过所有gate最大速度。思路呢,自然是二分速度了。每次我们求出经过一个gate后,能到达的最左边的位置left,和最右边的位置right。与下一个gate的横坐标进行比较。如果二者有交集,那么说明可以滑进去,修正下左右位置,继续;如果不能,说明垂直速度太快了,需要用更慢的速度去滑,这样水平位移可以更大一点。
中间求位移的地方没有直接除速度sj,而是让其他变量乘上sj,确保精度。代码如下:
- #include <iostream>
- #include <cstdio>
- #include <algorithm>
- #include <cstring>
- #include <cmath>
- #include <vector>
- #include <queue>
- #include <map>
- #include <string>
- using namespace std;
-
- #define ff(i, n) for(int i=0;i<(n);i++)
- #define fff(i, n, m) for(int i=(n);i<=(m);i++)
- #define dff(i, n, m) for(int i=(n);i>=(m);i--)
- typedef long long LL;
- typedef unsigned long long ULL;
- void work();
-
- int main()
- {
- #ifdef ACM
- freopen("in.txt", "r", stdin);
- #endif // ACM
-
- work();
- }
-
- /*****************************************/
-
- int x[111111], y[111111];
- int spd[1111111];
-
- int w, vh, n;
-
- bool check(int vv)
- {
- LL left = (LL)x[0]*vv, right = (LL)(x[0] + w)*vv;
-
- ff(i, n-1)
- {
- LL len = (LL)(y[i+1]-y[i]) * vh;
-
- if(left-len > (LL)(x[i+1]+w)*vv) return false;
- if(right+len < (LL)x[i+1]*vv) return false;
-
- left = max((LL)x[i+1]*vv, left-len);
- right = min((LL)(x[i+1]+w)*vv, right+len);
- }
-
- return true;
- }
-
- void work()
- {
- int T;
- scanf("%d", &T);
- ff(cas, T)
- {
- scanf("%d%d%d", &w, &vh, &n);
-
- ff(i, n) scanf("%d%d", x+i, y+i);
-
- int s;
- scanf("%d", &s);
- ff(i, s) scanf("%d", spd+i);
- sort(spd, spd+s);
- s = unique(spd, spd+s) - spd;
-
- int l = 0, r = s - 1;
- while(l <= r)
- {
- int m = (l+r)/2;
-
- if(check(spd[m]))
- l = m + 1;
- else
- r = m - 1;
- }
-
- if(r == -1)
- puts("IMPOSSIBLE");
- else
- printf("%d\n", spd[r]);
- }
- }

Copyright © 2003-2013 www.wpsshop.cn 版权所有,并保留所有权利。