二分算法是一种查找算法,是最基础的,最简单易学且高效实用的算法之一。
适用条件:序列有序,答案可以在一定范围内判断
时间复杂度O(logn)
例题:S(n)=1+2+...+n;给定s,按照要求求出n;
1.求出第一个大于等于给定数字的n
//不下降序列二分
#include<iostream>
using namespace std;
int a[10005];
int main()
{
int stand;
for(int i=1;i<=10000;i++)
a[i]=a[i-1]+i;
while(cin>>stand)
{
int tail=10001,head=0,mid,ans;
while(head<=tail)
{
mid=(head+tail)/2;
if(a[mid]>=stand)
ans=mid,tail=mid-1; //关键
else
head=mid+1;
}
cout<<ans<<endl; //求出第一个大于等于的数字的n
}
return 0;
}
//不下降序列二分
#include<iostream>
using namespace std;
int a[10005];
int main()
{
int stand;
for(int i=1;i<=10000;i++)
a[i]=a[i-1]+i;
while(cin>>stand)
{
int tail=10001,head=0,mid,ans;
while(head<=tail)
{
mid=(head+tail)/2;
if(a[mid]>stand)
ans=mid,tail=mid-1; //关键
else
head=mid+1;
}
cout<<ans<<endl; //求出第一个大于给定数字的n
}
return 0;
}
3.求出最后一个小于给定数字的n
//不下降序列二分
#include<iostream>
using namespace std;
int a[10005];
int main()
{
int stand;
for(int i=1;i<=10000;i++)
a[i]=a[i-1]+i;
while(cin>>stand)
{
int tail=10001,head=0,mid,ans;
while(head<=tail)
{
mid=(head+tail)/2;
if(a[mid]>=stand)
tail=mid-1;
else
ans=mid,head=mid+1; //关键
}
cout<<ans<<endl; //求出最后一个小于给定数字的n
}
return 0;
}
//不下降序列二分
#include<iostream>
using namespace std;
int a[10005];
int main()
{
int stand;
for(int i=1;i<=10000;i++)
a[i]=a[i-1]+i;
while(cin>>stand)
{
int tail=10001,head=0,mid,ans;
while(head<=tail)
{
mid=(head+tail)/2;
if(a[mid]>stand)
tail=mid-1;
else
ans=mid,head=mid+1; //关键
}
cout<<ans<<endl; //求出最后一个小于等于给定数字的n
}
return 0;
}
其他问法和不上升序列二分的用法只要略加改动就好,这里就不在列举了
另外C++STL中也有相应的二分算法,详情请点击下面的链接