經典二分算法詳解

二分算法是一種查找算法,是最基礎的,最簡單易學且高效實用的算法之一。

適用條件:序列有序,答案可以在一定範圍內判斷

時間複雜度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;
}


2.求出第一個大於給定數字的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;
}

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;
}


4.求出最後一個小於等於給定數字的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;
}

其他問法和不上升序列二分的用法只要略加改動就好,這裏就不在列舉了

另外C++STL中也有相應的二分算法,詳情請點擊下面的鏈接

C++STL實現二分算法


發表評論
所有評論
還沒有人評論,想成為第一個評論的人麼? 請在上方評論欄輸入並且點擊發布.
相關文章