贪心解法
\(∣a−b∣=\max(a−b,b−a)\)
由绝对值的性质易证。
那么直接把 \(t_i\) 算到距离中,转换成求最左和最右“坐标”的中间点的简单问题。
//通过把t[i]算到距离中,转换成求最左和最右坐标的中间点的简单情况
void solve()
{
#define tests
int n;
std::cin >> n;
std::vector<int> x(n), t(n);
for (int i = 0; i < n; i++) std::cin >> x[i];
for (int i = 0; i < n; i++) std::cin >> t[i];
std::vector<int> a;
for (int i = 0; i < n; i++) {
a.push_back(x[i] + t[i]);
a.push_back(x[i] - t[i]);
}
int mn = a[0], mx = a[0];
for (int val : a) {
mn = std::min(mn, val);
mx = std::max(mx, val);
}
int sum = mn + mx;
std::cout << sum / 2;
if (sum % 2 != 0)
std::cout << ".5";
std::cout << '\n';
}
二分解法
对 \(x_0\) 进行二分,判断左边和右边谁到达 \(x_0\) 的最大时间更大
如果左边距离更大,就往左边靠近继续二分
void solve() {
#define tests
int n;
scanf("%d", &n);
std::vector<i64> a(n);
std::vector<i64> t(n);
for (auto& x : a) scanf("%d", &x);
for (auto& x : t) scanf("%d", &x);
double lo(0), hi(*std::max_element(all(a)));
int res(0);
auto check = [&](auto X) -> bool {
double lMax(0), rMax(0);
for (int i = 0; i < n; i++) {
if (a[i] < X) {
lMax = std::max(lMax, X - a[i] + t[i]);
}
else {
rMax = std::max(rMax, a[i] - X + t[i]);
}
}
return rMax < lMax;
};
constexpr double eps(1E-7);
while(hi - lo > eps) {
double mid((lo + hi) / 2.0);
if (check(mid)) {
hi = mid;
}
else {
lo = mid;
}
}
printf("%.6lf\n", hi);
}
三分解法
三分法适用于给出 \(N\) 个函数,保证在范围内存在一点 \(x\),使得左边界 \(x\) 上单调增,\(x\) 到右边界上单调减。
可以用三分求出 \(\max(f_1(x), f_2(x), f_3(x), \dots, f_n(x))\) 取最小时,对应的 \(x\) 的值。
而这题的绝对值函数 \(T_i = t_i + \left | x_i - x_0 \right |\) 满足条件,所以直接对 \(x_0\) 进行三分。
int _, n, a[N], t[N];
double f(double x, LL i) {
return (fabs(a[i] - x) + t[i]);
}
double check(double x) {
double res = f(x, 1);
for (int i = 2; i <= n; i++) {
res = max(res, f(x, i));
}
return res;
}
void solve() {
cin >> n;
for (LL i = 1; i <= n; i++) cin >> a[i];
for (LL i = 1; i <= n; i++) cin >> t[i];
double m1, m2, l = 0, r = 0x3f3f3f3f;
while (r - l > eps) {
m1 = l + (r - l) / 3.0;
m2 = r - (r - l) / 3.0;
if (check(m1) > check(m2)) {
l = m1;
// 如果m1对应的函数最大值比m2对应的值要大。
// 则说明左边界l需要收敛
}
else {
r = m2;
// 如果m2对应的函数最大值比m1对应的值要大。
// 则说明右边界r需要收敛
}
}
printf("%.7lf\n", l);
}
标签:二分,std,max,题意,int,double,m1,m2,CF1730B
From: https://www.cnblogs.com/kdlyh/p/18068836