D
题意:
总共需要移动n次,每次移动的距离不超过 k,且第i次移动到的位置 x 需要满足 li <= x <= ri
需要确定最小 k 值。
特征捕捉:
1.求最值。2.该值需要n次检验。3.k值越小越不容易通过所有的检验。
解法:
二分 + check。注意check函数的逻辑,需要判断一个指定的值是否可以通过所有的检验,我们需要知道当前可以跳跃的范围,如果当前的范围与 li ~ ri 这个范围有交集则继续检验,直到结束。如果没有交集则直接跳出循环,return false。
代码:
#include <iostream>
#include <vector>
#include <algorithm>
using namespace std;
int n;
bool check(int x, vector<int> &le, vector<int> &ri) {
int ll = 0, rr = 0;// ll 表示当前可跳跃范围的左端点,rr 表示当前可跳跃范围的右端点。
int judge = 1;
for (int i = 0; i < n; i++) {
ll = ll - x; rr = rr + x;
if (ll > ri[i]) {
judge = 0;
break;
}
if (rr < le[i]) {
judge = 0;
break;
}
ll = max(ll, le[i]); rr = min(rr, ri[i]);
}
if (judge == 1) return true;
else return false;
}
int main() {
int t;
cin >> t;
while (t--) {
cin >> n;
vector<int> le(n);
vector<int> ri(n);
for (int i = 0; i < n; i++) {
cin >> le[i] >> ri[i];
}
int l = 0, r = 1e9;
while (l <= r) {
int mid = (l + r) / 2;
if (check(mid, le, ri)) r = mid - 1;
else l = mid + 1;
}
cout << l << endl;
}
return 0;
}
157

被折叠的 条评论
为什么被折叠?



