二分查找:针对有序序列,相似于单调函数零点的寻找。
二分答案:即猜答案的区间,然后二分选择答案,看能否满足题意。
P1. 以洛谷P1873砍树为例
可以采用二分答案的方式找到这个数,也就是搜索到一个值a满足得到木材数大于M时,继续向上搜索答案,若都不满足,则a就是所求,这里采用递归写二分(区间有包含关系),所以注意递归的格式,要有终止条件。
#include<iostream>
#include<vector>
using namespace std;
#define ll long long
ll ans=0;
void binaryans(vector<int> &a,int m,ll left,ll right)
{
if(left>right) return;//递归必有终止条件
ll mid=(right+left)/2;
ll sums=0;
for(int i=0;i<a.size();i++)//size才是元素个数,sizeof是字节数
if(mid<a[i]) sums+=(a[i]-mid);
if(sums>=m)
{
ans=mid;
binaryans(a,m,mid+1,right);
}
else binaryans(a,m,left,mid-1);
}
int main()
{
int N,M;cin>>N>>M;
vector<int> trees;
for(int i=0;i<N;i++)
{
int p;cin>>p;
trees.push_back(p);
}
ll right=2e9;
ll left=0;
binaryans(trees,M,left,right);
cout<<ans<<endl;
return 0;
}
.