题意
给一条路,范围是 \([0,l]\) ,两辆车分别从左右向中间开,速度都是1。路中间有若干个旗子,每经过一个旗子,车的速度会上升1。问多少时间之后两车会相遇?
题解
这个时间值明显是可以二分的,“已经相遇”当且仅当两车经过的总路程超过 \(l\) 。那么问题转换问怎么求指定时间内某车经过的总路程,贪心即可。
const double EPS = 1e-9;
int n, l;
int a[300005];
bool Check(double t) {
double sa = 0, va = 1, ta = t;
for(int i = 1; i <= n + 1; ++i) {
double tt = min(ta, (a[i] - sa) / va);
ta -= tt;
sa += tt * va;
va += 1;
if(abs(ta) <= EPS)
break;
}
double sb = l, vb = 1, tb = t;
for(int i = n; i >= 0; --i) {
double tt = min(tb, (sb - a[i]) / vb);
tb -= tt;
sb -= tt * vb;
vb += 1;
if(abs(tb) <= EPS)
break;
}
return sb <= sa;
}
double BinarySearch() {
double L = 0, R = l;
for(int t = 120; t; --t) {
double M = (L + R) / 2;
if(Check(M))
R = M;
else
L = M;
}
return abs((L + R) / 2);
}
void solve() {
scanf("%d%d", &n, &l);
for(int i = 1; i <= n; ++i)
scanf("%d", &a[i]);
a[0] = 0, a[n + 1] = l;
printf("%.9f\n", BinarySearch());
return;
}