HDU - 6581 Vacation
题意:在马路上有n辆车在你前方,每辆车有三个属性:车长,车头离终点线距离,最大速度;
道路狭窄不能超车,问你最快多久能到达终点,每辆车到达终点之后还是会继续行驶,当你的车头到达终点时就认为你到达了终点
思路:一眼二分时间,关键是怎么check:
考虑我到达终点时前面的车需要到达的位置:终点向前走prl[i],prl[i]是l[i]去掉l[0]的前缀和,
那么在check的t时间下按离终近计算每个车离应到的位点远置的距离les[i],les[i]受他前一个车的位置和v[i]影响,
即max({les[i+1],s[i] + prl[i] - t*v[i],0})
考虑les[0]的意义:因为prl[0] = 0,那么你的车车头应到的位置就是终点,如果les[0]<=0,那么就是到达了终点否则就没到达
时间复杂度o(60*n)
如果tle建议换scanf,关闭同步流没用....
const double esp = 1e-7;
const int maxn = 1e5 + 7;
int n;
double l[maxn], s[maxn], v[maxn], les[maxn], tot, prl[maxn];
bool check(double t) {
for (int i = 0; i <= n; i++)
les[i] = s[i] + tot;//最远车头到终终点的距离
les[n + 1] = 0;
for (int i = n; i >= 0; i--)
les[i] = max(les[i + 1], max(s[i] + prl[i] - t * v[i], 0));
return les[0] <= esp;
}
int main(){
while (scanf("%d",&n)!=EOF) {
tot = 0;
for (int i = 0; i <= n; i++)
scanf("%lf",&l[i]), tot += l[i];
for (int i = 1; i <= n; i++)
prl[i] = prl[i - 1] + l[i];
for (int i = 0; i <= n; i++)
scanf("%lf",&s[i]);
for (int i = 0; i <= n; i++)
scanf("%lf",&v[i]);
double pl = 0.0, pr = 1e10;
int cnt = 60;
while (cnt--) {
if (check((pl + pr) / 2.0)) {
pr = (pl + pr) / 2.0;
} else {
pl = (pl + pr) / 2.0;
}
}
printf ("%.9f\n",pl);
}
}
我看见 你

浙公网安备 33010602011771号