当前位置:网站首页>二分函数细节
二分函数细节
2022-07-23 21:32:00 【SKT T1 Faker .】
在打ACM竞赛题时,二分是一种很基础的方法,但是有些时候往往疏忽了一些细节,导致二分循环可能会卡死,或者有BUG存在。
所以在下面总结一下二分函数的细节使用方法:
二分的基本规则:
在a[mid]<key 的时候,变化 l(左端点)
在a[mid]>key 的时候,变化 r (右端点)
当然上述规则,只是在 数组升序的情况下才成立
如果mid 和 key时成负相关 的情况下,上面的规则要倒过来
例如:二分城市投票点的最大人数时,在人数一定下,由于投票点人数越多,那么需要的投票点就越少,每个投票点人数越少,需要的投票点就越多,这种情况就需要把基本规则倒过来。
在这种情况下,只需要把上面这个基本规则反过来,其他规则都和正常一样就行
所以要具体情况,具体分析。
普通的二分
(l<=r)型二分
特点,在l,r变化的时候需要遵循
mid+1 和 r= mid-1 的规则
并且,如果 当判断条件时 a[mid]<=key时,r为二分的答案, r=l-1;
同样,当判断条件为 a[mid]>=key时,l为二分的答案,l=r+1;
(在变化时,等号在哪个变量上判断,答案就是另一个变量)
l为答案时:
用处:输出key的正确位置,找不到时输出第一个比key大的数字的位置
并且当有重复key时,输出第一个key的位置!
#include<bits/stdc++.h>
using namespace std;
int a[11];
int main()
{
for(int i=1;i<=10;i++)//2 4 6 8 10
{
a[i]=i*2;
}
int k;
cin>>k;
int l=1,r=10;
int mid;
while(l<=r)
{
mid=(l+r)/2;
cout<<l<<" "<<r<<" "<<mid<<endl;
if(a[mid]>=k)
{
r=mid-1;
}
else
l=mid+1;
}
cout<<l;//能输出准确答案,或者输出第一个比自己大的数字的位置!
return 0;
}
r为答案时
用处:输出key的位置,找不到时输出第一个比自己小的数字的位置
当有重复的key时,输出最后一个key的位置!
#include<bits/stdc++.h>
using namespace std;
int a[11];
int main()
{
for(int i=1;i<=10;i++)
{
a[i]=i*2;
}
int k;
cin>>k;
int l=1,r=10;
int mid;
while(l<=r)
{
mid=(l+r)/2;
cout<<l<<" "<<r<<" "<<mid<<endl;
if(a[mid]>k)
{
r=mid-1;
}
else
l=mid+1;
}
cout<<r;//能输出正确答案,并且能输出第一个比自己小的数字的位置!
return 0;
}
(l<r-1)型二分
在l,r变化的时候,需要遵循
l=mid 和 r=mid 的区别 。
投票点
#include<bits/stdc++.h>
using namespace std;
int n,m;
int t[5001];
int judge(int mid)
{
int num=0;
for(int i=1;i<=m;i++)
{
num+=t[i]/mid;
if(t[i]%mid!=0)
num++;
}
return num;
}
int main()
{
cin>>n>>m;
int mmax=-1;
for(int i=1;i<=n;i++)
{
cin>>t[i];
mmax=max(mmax,t[i]);
}
int l=0,r=mmax;
while(l<r-1)
{
int mid=(l+r)/2;
if(judge(mid)<=m)
{
r=mid;
}
else
{
l=mid;
}
}
cout<<r;
return 0;
}
用 l<=r型改写
#include<bits/stdc++.h>
using namespace std;
int t[5001];
int n,m;
int judge(int mid)
{
int num=0;
for(int i=1;i<=m;i++)
{
num+=t[i]/mid;
if(t[i]%mid!=0)
num++;
}
return num;
}
int main()
{
cin>>n>>m;
int mmax=-1;
for(int i=1;i<=n;i++)
{
cin>>t[i];
mmax=max(mmax,t[i]);
}
int l=0,r=mmax;
while(l<=r)
{
int mid=(l+r)/2;
if(judge(mid)<=m)
{
r=mid-1;
}
else
l=mid+1;
}
cout<<l;
return 0;
}
边栏推荐
- Uncertainty of distributed energy - wind speed test (realized by matlab code)
- Connect with Hunan Ca and use U_ Key login
- Complete set of official openlayers instances
- 启牛是什么?请问一下手机开户股票开户安全吗?
- Openlayers instance animated GIF GIF animation
- scala编程(初级)
- H264 encoding parameters
- It's good to change jobs for a while, and it's good to change jobs all the time?
- Scala programming (elementary)
- [shader realizes roundwave circular ripple effect _shader effect Chapter 6]
猜你喜欢

High numbers | calculation of double integral 3 | high numbers | handwritten notes

宇树A1机器狗手势控制

Protocol buffers 的问题和滥用

At 12 o'clock on July 23, 2022, the deviation from the top of the line of love life hour appeared, maintaining a downward trend and waiting for the rebound signal.

Union and union all of Hana SQL

2022-7-23 12点 程序爱生活 小时线顶背离出现,保持下跌趋势,等待反弹信号出现。

Opencv image processing Laplace pyramid

【愚公系列】2022年06月 .NET架构班 084-微服务专题 Abp vNext微服务通信

High numbers | calculation of triple integral 2 | high numbers | handwritten notes

集群聊天服務器:數據庫錶的設計
随机推荐
Kuberntes云原生实战六 使用Rook搭建Ceph集群
googletest
Use code to set activity to transparent
[shader realizes roundwave circular ripple effect _shader effect Chapter 6]
告诉我十大证券公司?请问网上开户安全么?
scala编程(初级)
Leetcode hot topic hot52-100
VLAN comprehensive experiment
分布式能源的不确定性——风速测试(Matlab代码实现)
Cesium keyboard and mouse control camera roaming (source code + principle explanation)
Opencv image processing Laplace pyramid
Scala programming (elementary)
Union and union all of Hana SQL
2022-7-23 12点 程序爱生活 小时线顶背离出现,保持下跌趋势,等待反弹信号出现。
Chapter1 data cleaning
NLP field history most complete must read classic papers classification, sorting and sharing (with Chinese analysis)
比较关注证券公司究竟哪个佣金最低?请问网上开户安全么?
Day109.尚医通:集成Nacos、医院列表、下拉列表查询、医院上线功能、医院详情查询
[wechat applet] do you know about applet development?
It's good to change jobs for a while, and it's good to change jobs all the time?