CSP 2022 备战——二分答案
二分,一个重要的算法
在抽象意义上,就是将递增1的数列分成两份
看它是否满足,再继续分割这个数列
看起来很抽象是吧
比方说,这里有一个数列:1 2 3 4 5 6 7 8 9
我们要找其中一个数的平方=16
对与我们来说,可以一眼看出要找的数是4,第二眼就能确定5的位置
可是计算机不行,所以二分查找闪亮登场
令头head=1,尾tail=9
9的平方是81对吧,所以我们就修改tail,取head+tail的一半也就是5
可是5还是大,那就再取head+tail的一半也就是3
这回3的平方相较16较小,所以我们这次修改head到3
再一次取head和tail的中间值,也就是4
靠着这种方式,我们可以很快确定答案
它的应用性就在于,在一些答案不确定的情况下,可以通过这种查找的方式来确定答案
时间复杂度约为O(log2n)
代码实现:
int x(int n,int k)
{
int left=0;
int right=k-1;
while(left<=right)
{
int mid=(left+right)/2;
if (a[mid]==n)
{
return mid;
}
if (a[mid]>=n)
{
right=mid-1;
}
else
{
left=mid+1;
}
}
return -1;
}
这就是一个在0到right之间查找的算法
了解了二分查找,那么二分答案也呼之欲出了
现在给定一个升序数组a[n],想查找k在第几个
令“条件”为a[x]大于或等于k,要找最小的x使条件成立
那就可以运用二分查找的思想,先检验数组中间值mid
就可以分为left-mid到mid+1到right上
使用条件:
1.命题可以被归纳成找到使得P(x)(不)成立的最大(小)的x值
2.吧它看作一个bool函数,则它在某一分界线一侧全为真,另一侧全为假
换句话说,二分答案可以用来处理“最大的最小”或“最小的最大”的问题
这就是使用二分答案的基本条件
典中典:
P2678,看一下它是如何判断的
bool check(int dis) { int count=0,last=0;//count代表移走石头的数量,last模拟当前位置 for(int i=1;i<=n;i++) if(a[i]-last<dis)count++;//如果条件符合就移走这块石头 else last=a[i];//反之就跳过去 if(count>m)return 0;return 1;//设置终止条件,即移走的石头至多为m }

浙公网安备 33010602011771号