算法学习-二分查找

题目:C. Place for a Selfie Codeforces Round 862(Div.2)

题目链接:Problem - C - Codeforces

题目描述:

   有若干抛物线(抛物线方程为a * x2 + b * x + c,每条抛物线的a,b,c值给出)和经过原点,斜率不同的直线(斜率值k给出)。对于每条抛物线找出任意一条直线,它与该抛物线不相交。
题目分析:

  直线与抛物线不相交,有公式(b - k)2 - 4  * a * c < 0,所以我们需要找这样一条直线,它的斜率k最接近b值(贪心思想:使公式左边尽可能小)。使用数组将所有直线斜率值存储起来并排序,使用二分查找出最接近b的那个斜率值。

  注意点:在我们找到的斜率右边可能存在一个斜率,使得上述公式左边更小

 

知识点补充:二分查找:

lower_bound(begin, end, target)函数:在数组中查询大于等于的目标的第一个下标

    int arr[5]{1, 3, 3, 5, 9};
    cout << lower_bound(arr, arr + 5, 3) - arr << endl; //输出值为1,解释:在数组中找到了第一个3,其下标为1
    cout << lower_bound(arr, arr + 5, 4) - arr << endl; //输出值为3,解释:在数组中,4排在3之后,因此结果被记为3
    cout << lower_bound(arr, arr + 5, 100) - arr << endl; //输出值为5,解释:在数组中,100排在9之后,因此结果被记为5
    cout << lower_bound(arr, arr + 5, -1) - arr << endl; //输出值为0,解释:在数组中,-1排在1之前,因此结果被记为0

upper_bound(begin, end, target)函数:在数组中查询大于目标的第一个下标

    int arr[4]{1, 3, 3,5, 9};
    cout << upper_bound(arr, arr + 5, 3) - arr << endl; //输出值3,5是第一个大于3的值其下标为3
    cout << upper_bound(arr, arr + 5, 4) - arr << endl; //输出值3
    cout << upper_bound(arr, arr + 5, 100) - arr << endl; //输出值5
    cout << upper_bound(arr, arr + 5, -1) - arr << endl; //输出值0

二分查找的底层逻辑思考:

复制代码
int lower_bound(vector<int>& nums, int target) {
    int left = 0;
    int right = nums.size() - 1;

    while (left <= right) {
        int mid = left +(right - left) / 2;
        if (nums[mid] < target) { 
        // 中点值小于target,则移动右指针置为中点下标+1,不断进行二分,直到中点值能够大于等于target。
     // 对于upper_bound()来说,这里判断条件是num[mid] <= target,如果中点值小于等于target,则二分到中点值大于target。
left = mid + 1; } else { right = mid - 1; } } return left; }
复制代码

 

 
posted @   yang_ever  阅读(19)  评论(0编辑  收藏  举报
相关博文:
阅读排行:
· 地球OL攻略 —— 某应届生求职总结
· 周边上新:园子的第一款马克杯温暖上架
· Open-Sora 2.0 重磅开源!
· 提示词工程——AI应用必不可少的技术
· .NET周刊【3月第1期 2025-03-02】
点击右上角即可分享
微信分享提示