之前先学了y总的二分,后来又看了代码随想录的,感觉代码随想录的更好记忆
- 二分查找需要的数据必须是有序的。如果数据没有序,我们需要先排序,排序的时间复杂度最低是 O(nlogn)。
- 二分查找底层依赖的是数组,数组需要的是一段连续的存储空间,所以数据量太大不适合二分查找
- 查找的方法,顾名思义,就是若 target = arr[mid],则查找成功(找到了目标值)返回 mid 值
🚥🚥🚥
根据check()来划分区间
🚥🚥🚥
⭐整数二分
划分为[l,mid]和[mid+1,r]
int binary(int l,int r){
while(l<r){
int mid=(l+r)/2;
if(check(mid)) r=mid;
else l=mid+1;
}
return l;
}
划分为[l.mid-1]和[mid,r]
int binary(int l,int r){
while(l<r){
int mid=(l+r+1)/2;
if(check(mid)) l=mid;//如果先是l=mid,那么为(l+r+1).要+1
else r=mid+1;
}
return l;
}
⭐ 浮点数二分
int binary(int l,int r){
while(l-r>0.001){ //0.001可以又其他浮点数代替,但是都必须尽可能小
int mid=(l+r)/2;
if(check(mid)) r=mid;//l=mid
else l=mid; //r=mid
} //根据check()决定
return l;
}
class Solution {
public:
int searchInsert(vector<int>& nums, int target) {
int l=0,r=nums.size();
while(l<r)
{
int mid=(l+r)/2;
if(nums[mid]>target) r=mid;
else if(nums[mid]<target) l=mid+1;
else
return mid;
}
return l;
}
};
P1024 [NOIP2001 提高组] 一元三次方程求解 – 洛谷 | 计算机科学教育新生态 (luogu.com.cn)
#include<cstdio>
double a,b,c,d;
double fc(double x)
{
return a*x*x*x+b*x*x+c*x+d;
}
int main()
{
double l,r,mid,x1,x2;
int s=0,i;
scanf("%lf%lf%lf%lf",&a,&b,&c,&d);
for (i=-100;i<100;i++)
{
l=i;
r=i+1;
x1=fc(l);
x2=fc(r);
if(!x1)
{
printf("%.2lf ",l);
s++;
} //判断左端点,是零点直接输出。
//不能判断右端点,会重复。
if(x1*x2<0) //区间内有根。
{
while(r-l>=0.001) //二分控制精度。
{
mid=(l+r)/2;
if(fc(mid)*fc(r)<=0)
l=mid;
else
r=mid; //计算中点处函数值缩小区间。
}
printf("%.2lf ",r);
//输出右端点。
s++;
}
if (s==3) //每找到一个,s++,当s=3时,就找到了3个
break;
}
return 0;
}
🚥🚥🚥
下面这个题可以体会到check()选择区间的条件
得用两次二分,找到左右两个值
#include <iostream>
using namespace std;
const int N = 100010;
int n, m;
int q[N];
int main()
{
scanf("%d%d", &n, &m);
for (int i = 0; i < n; i ++ ) scanf("%d", &q[i]);
while (m -- )
{
int x;
scanf("%d", &x);
int l = 0, r = n - 1;
while (l < r)
{
int mid = l + r >> 1;
if (q[mid] >= x) r = mid;//>=x
else l = mid + 1;
}
if (q[l] != x) cout << "-1 -1" << endl;
else
{
cout << l << ' ';
int l = 0, r = n - 1;
while (l < r)
{
int mid = l + r + 1 >> 1;
if (q[mid] <= x) l = mid;//<=x
else r = mid - 1;
}
cout << l << endl;
}
}
return 0;
}
P8647 [蓝桥杯 2017 省 AB] 分巧克力 – 洛谷 | 计算机科学教育新生态 (luogu.com.cn)
或者
AcWing 1227. 分巧克力(寒假每日一题) – AcWing
注意是长和宽,得开二维数组
#include <iostream>
#include <algorithm>
using namespace std;
const int N = 100010;
int n, k;
int h[N], w[N];
bool check(int mid)
{
int res = 0;
for (int i = 0; i < n; i ++ )
{
res += (h[i] / mid) * (w[i] / mid);
if (res >= k) return true;
}
return false;
}
int main()
{
scanf("%d%d", &n, &k);
for (int i = 0; i < n; i ++ ) scanf("%d%d", &h[i], &w[i]);
int l = 1, r = 1e5;
while (l < r)
{
int mid = l + r + 1 >> 1;
if (check(mid)) l = mid;
else r = mid - 1;
}
printf("%d\n", r);
return 0;
}
版权声明:本文内容由互联网用户自发贡献,该文观点仅代表作者本人。本站仅提供信息存储空间服务,不拥有所有权,不承担相关法律责任。如发现本站有涉嫌侵权/违法违规的内容, 请发送邮件至 举报,一经查实,本站将立刻删除。
文章由极客之音整理,本文链接:https://www.bmabk.com/index.php/post/131436.html