• 算法基础学习|二分


    二分

    模板

    整数二分模板

    1. bool check(int x) {/* ... */} // 检查x是否满足某种性质
    2. // 区间[l, r]被划分成[l, mid]和[mid + 1, r]时使用(即寻找左边界使用):
    3. int bsearch_1(int l, int r)
    4. {
    5. while (l < r)
    6. {
    7. int mid = l + r >> 1;
    8. if (check(mid)) r = mid; // check()判断mid是否满足性质
    9. else l = mid + 1;
    10. }
    11. return l;
    12. }
    13. // 区间[l, r]被划分成[l, mid - 1]和[mid, r]时使用(即寻找右边界使用):
    14. int bsearch_2(int l, int r)
    15. {
    16. while (l < r)
    17. {
    18. int mid = l + r + 1 >> 1;
    19. if (check(mid)) l = mid;
    20. else r = mid - 1;
    21. }
    22. return l;
    23. }

    浮点数二分模板

    1. bool check(double x) {/* ... */} // 检查x是否满足某种性质
    2. double bsearch_3(double l, double r)
    3. {
    4. const double eps = 1e-6; // eps 表示精度,取决于题目对精度的要求
    5. while (r - l > eps)
    6. {
    7. double mid = (l + r) / 2;
    8. if (check(mid)) r = mid;
    9. else l = mid;
    10. }
    11. return l;
    12. }

    例题一

    题目

    给定一个按照升序排列的长度为 n 的整数数组,以及 q 个查询。

    对于每个查询,返回一个元素 k 的起始位置和终止位置(位置从 0 开始计数)。

    如果数组中不存在该元素,则返回 -1 -1

    输入格式

    第一行包含整数 n 和 q,表示数组长度和询问个数。

    第二行包含 n 个整数(均在 1 \sim 10000 范围内),表示完整数组。

    接下来 q 行,每行包含一个整数 k,表示一个询问元素。

    输出格式

    共 q 行,每行包含两个整数,表示所求元素的起始位置和终止位置。

    如果数组中不存在该元素,则返回 -1 -1

    数据范围

    1\leq n\leq 100000

    1\leq k\leq 10000

    1\leq q\leq 10000

    输入样例

    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
    2. using namespace std;
    3. int main() {
    4. int n, t;
    5. cin >> n >> t;
    6. int* array = new int[n];
    7. for (int i = 0; i < n; i++) {
    8. cin >> array[i];
    9. }
    10. while (t--) {
    11. int num;
    12. cin >> num;
    13. //寻找左边界
    14. int l = 0, r = n - 1;
    15. while (l < r) {
    16. int mid = l + r >> 1;
    17. if (array[mid] >= num) r = mid;
    18. else l = mid + 1;
    19. }
    20. if (array[l] != num) cout << "-1 -1" << endl;
    21. else {
    22. cout << l;
    23. //寻找右边界
    24. int l = 0, r = n - 1;
    25. while (l < r) {
    26. int mid = l + r + 1 >> 1;
    27. if (array[mid] <= num) l = mid;
    28. else r = mid - 1;
    29. }
    30. cout << " " << l << endl;
    31. }
    32. }
    33. }

    例题二

    题目

    给定一个浮点数 n,求它的三次方根。

    输入格式

    共一行,包含一个浮点数 n

    输出格式

    共一行,包含一个浮点数,表示问题的解。

    注意,结果保留 6 位小数。

    数据范围

    -10000\leq n\leq 10000

    输入样例

    1000.00

    输出样例

    10.000000

    代码示例

    1. #include
    2. #include
    3. #include
    4. #include
    5. using namespace std;
    6. const double eps = 1e-8; // eps 表示精度,取决于题目对精度的要求
    7. int main() {
    8. double n;
    9. cin >> n;
    10. double l, r;
    11. //注意开根号的范围,1是特殊点
    12. if (n >= 1) l = 1, r = n;
    13. else if (n > 0) l = 0, r = 1;
    14. else if (n <= -1) l = n, r = -1;
    15. else l = -1, r = 0;
    16. while (r - l > eps)
    17. {
    18. double mid = (l + r) / 2;
    19. if (pow(mid, 3) >= n) r = mid;
    20. else l = mid;
    21. }
    22. cout << fixed << setprecision(6) << l << endl;
    23. return 0;
    24. }

  • 相关阅读:
    6_sleuth-zipkin-spring_boot_admin 链路追踪
    人工智能 | ShowMeAI资讯日报 #2022.06.28
    springboot导入excel(POI)
    JDK发布信息、历史及未来规划
    近期分享学习心得3
    老卫带你学---leetcode刷题(8. 字符串转换整数 (atoi))
    1445 雉兔同笼
    算法-排序算法
    蒙特卡洛树搜索方法介绍——算力聚焦方法(二) 反向聚焦(优先级遍历)
    记一次 cmd 打开 python 报错,环境变量已配置
  • 原文地址:https://blog.csdn.net/2203_75720729/article/details/133908535