hihoCoder 1128 二分·二分查找

来源:互联网 发布:ldc数据下载 编辑:程序博客网 时间:2024/05/13 13:38

二分查找适用于“有序”的情况,即一次能排除一半备选答案。在本题中,当数列无序时,我们不能直接利用二分查找,但是,我们可以利用求第k小数的思路,即用partition一次排除一半。这里的partition同quick-sort中的partition是一样的,原理很简单,但实现起来要注意细节,比如指针的推进,元素的交换。

#include<iostream>#include<vector>#include<algorithm>#include<fstream>//#define debugusing namespace std;int partition(int l,int r,vector<int>& nums){        int mid=l+(r-l)/2;        int tmp=nums[mid];        nums[mid]=nums[l];        int forwardIndex=l+1;        int backwardIndex=r;        while(forwardIndex!=backwardIndex)        {            while(nums[forwardIndex]<tmp)            {                ++forwardIndex;                if(forwardIndex==backwardIndex)                {                    nums[l]=nums[forwardIndex-1];                    nums[forwardIndex-1]=tmp;                    return forwardIndex-1;                }            }            do            {                backwardIndex--;                if(forwardIndex==backwardIndex)                {                    nums[l]=nums[forwardIndex-1];                    nums[forwardIndex-1]=tmp;                    return forwardIndex-1;                }            }while(nums[backwardIndex]>tmp);            int a=nums[forwardIndex];            nums[forwardIndex]=nums[backwardIndex];            nums[backwardIndex]=a;            forwardIndex++;        }        nums[l]=nums[forwardIndex-1];        nums[forwardIndex-1]=tmp;        return forwardIndex-1;}int main(){    #ifdef debug    ifstream cin("E:\\cppfiles\\input.txt");    #endif // debug    int n,k;    cin>>n>>k;    vector<int> nums(n,0);    for(int i=0;i<n;++i)    {        cin>>nums[i];    }    int start=0;    int end=n;    int res=-1;    while(start<end)    {        int pos=partition(start,end,nums);        if(k==nums[pos])        {            res=pos+1;            break;        }        if(nums[pos]>k)        {            end=pos;        }        else        {            start=pos+1;        }    }    cout<<res<<endl;    return 0;}


0 0