博客
关于我
强烈建议你试试无所不能的chatGPT,快点击我
noip模拟赛 读
阅读量:5108 次
发布时间:2019-06-13

本文共 1500 字,大约阅读时间需要 5 分钟。

分析:感觉很像是贪心,但是直接贪找不到方法.一个暴力的想法是枚举最小步数,然后看每个指针能够覆盖到的位置,看看能不能覆盖到所有点.这个求最大覆盖就有点贪心的思想,因为给的ai,bi都是递增顺序的,考虑第i个指针,如果左边还有点没有覆盖到是一定要去覆盖的,剩下的步数可以一直往右走.这样的话有两种情况,要么是先把左边的覆盖了再往右走,要么是先尽量往右走,之后返回刚好把最左边的那个点给覆盖,讨论一下就可以了.如果左边没有点要覆盖,i尽量往右走就可以了.最后看被覆盖的指针是不是有m个即可.

      由于ai,bi非常大,枚举最小步数要消耗太多的时间,需要进行优化.仔细揣摩一下这个过程就会发现这很像二分+check,因为枚举最小步数是从小到大枚举的嘛,所以符合单调性,二分即可.

枚举答案并判断是否可行的暴力做法可以优化为二分.

#include 
#include
#include
#include
using namespace std;typedef long long ll;int n, m;ll a[100010], b[100010], ans;bool check(ll x){ ll j = 1; for (int i = 1; i <= n; i++) { if (a[i] - b[j] > x) return false; ll can = 0; if (b[j] < a[i]) { ll rest = x - (a[i] - b[j]); can = max(b[j] + rest, a[i] + rest / 2); if (can < a[i]) can = a[i]; } else can = a[i] + x; while (j <= m && b[j] <= can) j++; if (j > m) return true; } return false;}int main(){ scanf("%d%d", &n, &m); for (int i = 1; i <= n; i++) scanf("%lld", &a[i]); for (int i = 1; i <= m; i++) scanf("%lld", &b[i]); ll l = 0, r = 20000000010; while (l <= r) { ll mid = (l + r) >> 1; if (check(mid)) { ans = mid; r = mid - 1; } else l = mid + 1; } printf("%lld\n", ans); return 0;}

 

转载于:https://www.cnblogs.com/zbtrs/p/7727555.html

你可能感兴趣的文章
Regular Experssion
查看>>
python中的字符编码
查看>>
图论例题1——NOIP2015信息传递
查看>>
uCOS-II中的任务切换-图解多种任务调度时机与问题
查看>>
CocoaPods的安装和使用那些事(Xcode 7.2,iOS 9.2,Swift)
查看>>
Android 官方新手指导教程
查看>>
幸运转盘v1.0 【附视频】我的Android原创处女作,请支持!
查看>>
UseIIS
查看>>
为什么int型最大的数是2147483647
查看>>
数据库连接的三层架构
查看>>
集合体系
查看>>
vi命令提示:Terminal too wide
查看>>
nyoj 5 Binary String Matching(string)
查看>>
引用 移植Linux到s3c2410上
查看>>
BizTalk 2010 单机安装
查看>>
人与人之间的差距是从大学开始的
查看>>
vue 开发过程中遇到的问题
查看>>
[Swift]LeetCode341. 压平嵌套链表迭代器 | Flatten Nested List Iterator
查看>>
MySQL5.7开多实例指导
查看>>
hdu 1029 Ignatius ans the Princess IV
查看>>