数的范围(二分)

举报
irrational 发表于 2022/01/18 22:25:17 2022/01/18
【摘要】 给定一个按照升序排列的长度为n的整数数组,以及q个查询。 对于每个查询,返回一个元素k的起始位置和终止位置(位置从О开始计数)。 如果数组中不存在该元素,则返回-1 -1。 输入格式 第一行包含整数n和q,表示数组长度和询问个数。 第二行包含n个整数(均在1~10000范围内),表示完整数组。 接下来q行,每行包含一个整数k,表示一个询...

给定一个按照升序排列的长度为n的整数数组,以及q个查询。
对于每个查询,返回一个元素k的起始位置和终止位置(位置从О开始计数)。
如果数组中不存在该元素,则返回-1 -1。
输入格式
第一行包含整数n和q,表示数组长度和询问个数。
第二行包含n个整数(均在1~10000范围内),表示完整数组。
接下来q行,每行包含一个整数k,表示一个询问元素。
输出格式
共q行,每行包含两个整数,表示所求元素的起始位置和终止位置。
如果数组中不存在该元素,则返回-1 -1。

输入样例:


  
  1. 6 3
  2. 1 2 2 3 3 4
  3. 3
  4. 4
  5. 5

输出样例:


  
  1. 3 4
  2. 5 5
  3. -1 -1

 


  
  1. #include <iostream>
  2. using namespace std;
  3. const int N = 100010;
  4. int n, m;
  5. int q[N];
  6. int main()
  7. {
  8. scanf("%d%d", &n, &m);
  9. for (int i = 0; i < n; i ++ ) scanf("%d", &q[i]);
  10. while (m -- )
  11. {
  12. int x;
  13. scanf("%d", &x);
  14. int l = 0, r = n - 1;
  15. while (l < r)
  16. {
  17. int mid = l + r >> 1;
  18. if (q[mid] >= x) r = mid;
  19. else l = mid + 1;
  20. }
  21. if (q[l] != x) cout << "-1 -1" << endl;
  22. else
  23. {
  24. cout << l << ' ';
  25. int l = 0, r = n - 1;
  26. while (l < r)
  27. {
  28. int mid = l + r + 1 >> 1;
  29. if (q[mid] <= x) l = mid;
  30. else r = mid - 1;
  31. }
  32. cout << l << endl;
  33. }
  34. }
  35. return 0;
  36. }

一招教你搞定二分:mid=l+r>>1之后看有机会l+r+1根据实际情况,一般先弄几个简单数据手动模拟一番,看会不会出现死循环,总之灵活为上!奥利给!

这个题要找到双重边界,那么就要二次二分。

文章来源: blog.csdn.net,作者:irrationality,版权归原作者所有,如需转载,请联系作者。

原文链接:blog.csdn.net/weixin_54227557/article/details/120594703

【版权声明】本文为华为云社区用户转载文章,如果您发现本社区中有涉嫌抄袭的内容,欢迎发送邮件进行举报,并提供相关证据,一经查实,本社区将立刻删除涉嫌侵权内容,举报邮箱: cloudbbs@huaweicloud.com
  • 点赞
  • 收藏
  • 关注作者

评论(0

0/1000
抱歉,系统识别当前为高风险访问,暂不支持该操作

全部回复

上滑加载中

设置昵称

在此一键设置昵称,即可参与社区互动!

*长度不超过10个汉字或20个英文字符,设置后3个月内不可修改。

*长度不超过10个汉字或20个英文字符,设置后3个月内不可修改。