1 条题解
-
1
#include <bits/stdc++.h> using namespace std; #define int long long #define double long double #define endl "\n" const int maxn = 2e5 + 7, oo = 1e18 + 7; int n, k, t, a[maxn]; bool ck(int x) { if (x == 0) return a[1] == a[n]; double tt = t; int l = k, r = k; int initl = 1, initr = 1; while (1) // !循环内剩余时间只增不减,所以每次循环左右区间可以扩大 { bool flag = 0; for (; r + initl <= n; initl++) // 记忆化 { if ((a[r + initl] - a[r]) / 2.0 / x > tt + t * (initl - 1)) // 能否遍历到此点 break; if (t * initl >= (a[r + initl] - a[r]) / 2.0 / x) // 能遍历到此点 贪心能加剩余时间的 { tt += t * initl - (a[r + initl] - a[r]) / 2.0 / x, r += initl, initl = 1, flag = 1; break; } } for (; l - initr >= 1; initr++) // 记忆化 { if ((a[l] - a[l - initr]) / 2.0 / x > tt + t * (initr - 1)) // 能否遍历到此点 break; if (t * initr >= (a[l] - a[l - initr]) / 2.0 / x) // 能遍历到此点 贪心能加剩余时间的 { tt += t * initr - (a[l] - a[l - initr]) / 2.0 / x, l -= initr, initr = 1, flag = 1; break; } } if (!flag) // 没有能增加时间的点 (退出循环之后 剩余时间不会比循环内更大 再无法扩大区间 [l-initl,r+initr]) break; } // 最好情况仅可以满足区间 [l-initl,r+initr], 区间之外不可满足 // 我们直接贪心覆盖剩余点即可 while (r != n && tt - (a[r + 1] - a[r]) / 2.0 / x >= 0) tt += t - (a[r + 1] - a[r]) / 2.0 / x, r += 1; while (l != 1 && tt - (a[l] - a[l - 1]) / 2.0 / x >= 0) tt += t - (a[l] - a[l - 1]) / 2.0 / x, l -= 1; return (l == 1 && r == n); } void solve() { cin >> n >> k >> t; for (int i = 1; i <= n; i++) cin >> a[i]; int l = 0, r = oo; while (l < r) { int m = (l + r) / 2; if (ck(m)) r = m; else l = m + 1; } cout << l << endl; } signed main() { ios::sync_with_stdio(0); cin.tie(0); cout.tie(0); cout << fixed << setprecision(10); int tt = 1; // cin >> tt; while (tt--) solve(); return 0; }
- 1
信息
- ID
- 215
- 时间
- 1000ms
- 内存
- 256MiB
- 难度
- 9
- 标签
- 递交数
- 27
- 已通过
- 2
- 上传者