事情的起因是 蓝桥杯的时候二分法调了半天还错了 于是我决定重新进行一个归纳与记忆
用记忆以及运用最好的方法

对于这种有序数组的查找 我们一般称其为二分查找
例如 大致几类问题
1.寻找大于5的第一个数的下标
2.寻找大于等于5的第一个数的下标
3.寻找大于5的最后一个数的下标…诸如此类
那么如何进行记忆呢
查找关于x的 check() 如果是对对对错型 则 mid<x或mid<=x 以此来确定分界线的位置
如果是错错错对型 则将数组逆序存储
然后我们再对l r的选取进行思考
如果是mid<4: 1 2 3 |4 4 4 4 6 8 边界即在|处 l是3 小于4的第一个数 r是4 大于等于4的第一个数
如果是mid<=4 1 2 3 4 4 4 4 4| 6 8 l是大于4的最后一个数
怎么记呢 条件<4 就是在小于4的第一个数前划一竖线
<=4 就是在最后一个<=4的数的右边划一个竖线

若有N个数 则从下标为1开始存
初始化l指针为0 r指针为N+1

[二分查找] [c++]
1
2
3
4
5
6
7
8
9
10
11
int l=0,r=N+1
while(l+1!=r)
{
int mid=(l+r)/2;
if(check(q[mid]))
{
l=mid;
}
else r=mid;
}

单调有序数组的二分查找就到此为止了
接下来是用的最多的 二分答案 这样的题就太多了

一般分为
1.最小值最大类型(满足条件的答案越来越大)
2.最大值最小类型

[2440] [c++]
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
#include <bits/stdc++.h>
using namespace std;
const int N=1e5+10;
int n,k,a[N];
bool check(int x);
int main()
{
cin>>n>>k;
int longest=0;
for(int i=1;i<=n;i++)
{
cin>>a[i];
if(a[i]>=longest) longest=a[i];

}
int l=0,r=longest;
while(l+1<r)
{
int mid=(l+r)/2;
if(check(mid)) l=mid;
else r=mid;
}
if(l<1) cout<<0<<endl;
else
{
if(check(r)) cout<<r<<endl;
else cout<<l<<endl;
}
return 0;
}
bool check(int x)
{
int sum=0;
for(int j=1;j<=n;j++)
{
sum+=(a[j]/x);
}
if(sum>=k) return true;
else return false;
}



[2678] [c++]
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
#include <bits/stdc++.h>
using namespace std;
const int N=1e5+7;
int a[N],ans;
bool check(int x,int b[],int n,int m)
{
int now=0,tot=0;
for(int j=1;j<=n+1;j++)
{
if(a[j]-a[now]<x) tot++;//如果距离小 这颗石头可以搬走
else
{
now=j;// 如果距离大,就跳过去
}
}
if(tot>m) return false;
else return true;
}

int main()
{
int L,n,m;
cin>>L>>n>>m;
for(int i=1;i<=n;i++) cin>>a[i];
a[n+1]=L;
int l=1,r=L;
while(l+1<r)
{
int mid=(l+r)>>1;
if (check(mid,a,n,m))
{
l=mid;
}
else r=mid;
}
if(check(r,a,n,m)) cout<<r<<endl;
else cout<<l<<endl;
return 0;
}

伐木那题 切的长度越短 越能分出k段 所以是对对对对错型

跳石头 最短跳跃很小 只要到其中最大的间隔 就行 一个石头都不用移动 如果要移动石头 就把最短距离调大 那么也是对对对对错型

插路标 空旷指数是相邻路标最大距离 如果最大距离特别小 那么需要很多的路标 可能就不够 如果最大距离很大很大 不需要插路标 也可以满足 所以是错错错对型 需要改成r=mid在先