题目:C. Place for a Selfie Codeforces Round 862(Div.2)
题目描述:
有若干抛物线(抛物线方程为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; }
标签:二分,直线,int,bound,斜率,算法,查找,抛物线 From: https://www.cnblogs.com/yang-ever/p/17438756.html