Codeforces Round 913 (Div. 3)

1|0基本情况

A、B题秒了。

C题找了好几个规律,一开始一直找错,但是最后终于对的。

因为C题耗时太久,D题看都没看。准备先做一下再补题。

2|0D. Jumping Through Segments

Problem - D - Codeforces

2|1思路

看了一下,明显二分答案,但是 check 不会写。

正解巧妙。

不是针对一个点,而是针对一整个区间来扩充(一堆点)。

维护两个变量 LR 来表示这整个区间。

  • L 是这个东西能到达最大区间的左边界
    • 通过 max(Lk,li) 来更新
      • Lk,这个区间上所有的点能扩充的边界肯定是最左边的点扩充的最大,即 Lk
      • 但是也必须满足这一步的时候要到达指定区域,左边界 li
  • R 是这个东西能到达最大区间的右边界
    • 通过 min(R+k,ri) 来更新
      • R+k,这个区间上所有的点能扩充的边界肯定是最右边的点扩充的最大,即 R+k
      • 但是也必须满足这一步的时候要到达指定区域,右边界 ri
  • 如果 L>R
    • 说明这个区间维护不下去了。
    • 那么这个 k 不合法

2|2代码

#include<iostream> #include<algorithm> #include<cstdio> const int N = 2e5 + 10; struct Query{ int l, r; void read() { std::cin >> l >> r; } }a[N]; int l, r; int mid; int n; bool check(int k) { int t = 0; int L = 0, R = 0; for (int i = 1; i <= n; i++) { L = std::max(L - k, a[i].l); R = std::min(R + k, a[i].r); if (L > R) {printf("L = %d, R = %d, k = %d\n", L, R, k);return false;} } return true; } int main() { std::ios::sync_with_stdio(false); std::cin.tie(nullptr); std::cout.tie(nullptr); int _; std::cin >> _; while(_--) { l = 0, r = 0; std::cin >> n; for (int i = 1; i <= n; i++) a[i].read(), r = std::max(r, a[i].r); while(l <= r) { mid = l + ((r - l) >> 1); if (check(mid)) r = mid - 1; else l = mid + 1; } std::cout << r + 1 << std::endl; } return 0; }

__EOF__

本文作者Kdlyh
本文链接https://www.cnblogs.com/kdlyh/p/17879238.html
关于博主:评论和私信会在第一时间回复。或者直接私信我。
版权声明:本博客所有文章除特别声明外,均采用 BY-NC-SA 许可协议。转载请注明出处!
声援博主:如果您觉得文章对您有帮助,可以点击文章右下角推荐一下。您的鼓励是博主的最大动力!
posted @   加固文明幻景  阅读(26)  评论(0编辑  收藏  举报
相关博文:
阅读排行:
· 无需6万激活码!GitHub神秘组织3小时极速复刻Manus,手把手教你使用OpenManus搭建本
· C#/.NET/.NET Core优秀项目和框架2025年2月简报
· Manus爆火,是硬核还是营销?
· 一文读懂知识蒸馏
· 终于写完轮子一部分:tcp代理 了,记录一下
点击右上角即可分享
微信分享提示