B. Meeting on the Line
https://codeforces.com/problemset/problem/1730/B
题意:给定长度为n的数组x和t,x代表所在的位置,位置可以移动,t代表移动前需要准备的时间。找一个point,使得x中的所有数字可以在最短的时间内全部到达。
思路:在时间域上二分,因为坐标可能是0.5的小数,所以将所有原始数据扩大一倍。随后,在二分时判断对于当前的时间节点T,如果T<t[i],则说明无解,因为还没有准备完,就没时间了。否则,求出当前x可以在T内到达的区间[x[i] -(T - t[i]), x[i] + (T - t[i])],然后对n个x求解区间交集,如果区间有交集,则说明在时间T内,x数组中所有的数字都可以在时间T内到达这个区间内,T是合法的,R左移,否则T不合法L右移。
总结:
inline void solve() {
int n;
cin >> n;
vector<int> x(n);
vector<int> t(n);
for (auto& a : x) {
cin >> a;
a <<= 1;
}
for (auto& v: t) {
cin >> v;
v <<= 1;
}
int ans;
auto valid = [&](int time) {
int l, r;
for (int i = 0; i < n; ++i) {
if (time < t[i]) {
return false;
}
int curLeft = x[i] - (time - t[i]);
int curRight = x[i] + (time - t[i]);
if (i) {
if (curRight < l || r < curLeft) {
return false;
}
l = max(l, curLeft);
r = min(r, curRight);
}
else {
l = curLeft;
r = curRight;
}
}
ans = r;
return true;
};
int l = 0, r = 4e8 + 10;
while (l < r) {
int mid = (l + r) >> 1;
if (valid(mid)) {
r = mid;
}
else {
l = mid + 1;
}
}
if (ans & 1) {
cout << ans / 2 << ".5" << '\n';
}
else {
cout << ans / 2 << '\n';
}
}

浙公网安备 33010602011771号