二分查找求解实在是看不出来了

【深基13.例1】查找

题目描述

输入 $n$ 个不超过 $10^9$ 的单调不减的(就是后面的数字不小于前面的数字)非负整数 $a_1,a_2,\dots,a_{n}$,然后进行 $m$ 次询问。对于每次询问,给出一个整数 $q$,要求输出这个数字在序列中第一次出现的编号,如果没有找到的话输出 $-1$ 。

输入格式

第一行 $2$ 个整数 $n$ 和 $m$,表示数字个数和询问次数。

第二行 $n$ 个整数,表示这些待查询的数字。

第三行 $m$ 个整数,表示询问这些数字的编号,从 $1$ 开始编号。

输出格式

输出一行,$m$ 个整数,以空格隔开,表示答案。

样例 #1

样例输入 #1

11 3
1 3 3 3 5 7 9 11 13 15 15
1 3 6

样例输出 #1

1 2 -1

提示

数据保证,$1 \leq n \leq 10^6$,$0 \leq a_i,q \leq 10^9$,$1 \leq m \leq 10^5$

本题输入输出量较大,请使用较快的 IO 方式。

#include 
using namespace std;
const int N = 10000005;
int arr[N];
int main(){
    int n,m;
    scanf("%d%d\n",&n,&m);
    for(int i = 1; i <= n; i++){
        scanf("%d",&arr[i]);
    }
    for(int j = 1; j <= m; j++){
        int left = 1;
        int right = n;
        int mid = (left + right) / 2;
        int x;
        scanf("%d",&x);
        while(true){
            if(arr[mid] > x){
                right = mid - 1;
                mid = (left + right) / 2;
            }
            if(arr[mid] < x){
                left = mid + 1;
                mid = (left + right) / 2;
            }
            if(arr[mid] == x) {
            break;
            }
            if(left > right) {
                printf("%d",-1);
                return 0;
            }
    }
        int b = 0;
        for(int i = 1; i < mid; i++){
            if(arr[mid-i]==arr[mid]) {
                b++;
            }
            else break;
        }
        printf("%d ",mid-b);
    }
    return 0;
}

img

代码


 int n,i_count;
    scanf("%d%d",&n,&i_count);
    int a[n+1];
    for(int i=0;i<n;++i)
    {
        scanf("%d",&a[i]);
    }
    for(int i=0;i<i_count;++i)
    {
        int k;
        scanf("%d",&k);
        int left=0,right=n-1;
        bool isFind=false;
        while(left<right)
        {
            int mid=left+(right-left)/2;
            if(a[mid]==k)
            {
                while(a[mid]==k)
                {
                    --mid;
                }
                isFind=true;
                printf("%d ",mid+2);
                break;
            }
            else if(a[mid]<k)
            {
                left=mid+1;
            }
            else
            {
                right=mid-1;
            }
        }
        if(!isFind)
            printf("%d ",-1);
    }