查找 (二分模板)

突发奇想练二分板子
二分具体思想就是一直找有序序列的中点值并将其与查找值相比,若比查找值大就说明查找值在序列左半段,反之则在右半段。
具体细节见代码:

#include <iostream>
using namespace std;
int A[1000005]; int n,m,a;
int chazhao(int t){
    int i=0,j=n-1,p=-2;
    while(i<=j){//二分查找
        int mid=(i+j)>>1;
        if(A[mid]>a){
            j=mid-1; continue;
        }
        if(A[mid]<a){
            i=mid+1; continue;
        }
        if(A[mid]==a){
            p=mid; break;
        }
    }
    if(p!=-2){
        while(A[p]==A[p-1]){//查看p是否是所求最小下标
            if(p==0) break;//特例,若所求值为0时下标肯减到负值
            p--;
        }
        return p;
    }
    return p;
}
int main(){
    cin>>n>>m;
    for(int i=0;i<n;i++) cin>>A[i];
    for(int i=0;i<m;i++){
        cin>>a;
        cout<<chazhao(a)+1<<" ";
    }
}

stl里面还有一对兄弟函数lower bound (返回大于或等于查找值的第一个数的指针)upper bound(返回大于查找值的第一个数的指针) ,注意他俩的区别。
具体见代码:

#include <iostream>
#include <vector>
using namespace std;
vector<int> A; int n,m,a;
int main(){
    cin>>n>>m;
    for(int i=0;i<n;i++) {
        int b; cin>>b; A.push_back(b);
    }
    for(int i=0;i<m;i++){
        cin>>a;
        int t=lower_bound(A.begin(),A.end(),a)-A.begin();//特别注意要减去A的地址
        if(A[t]!=a) cout<<-1<<" ";
        else cout<<t+1<<" ";
    }
}

题目出处:(https://www.luogu.com.cn/problem/P2249)

发布了24 篇原创文章 · 获赞 2 · 访问量 457

猜你喜欢

转载自blog.csdn.net/chineseherofeng/article/details/104808118
今日推荐