Java~~ 2022-11-23 17:24 采纳率: 100%
浏览 0
已结题

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

【深基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 <bits/stdc++.h>
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;
}

  • 写回答

1条回答 默认 最新

  • 加油吧,小杜 2022-11-23 17:55
    关注

    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);
        }
    
    
    本回答被题主选为最佳回答 , 对您是否有帮助呢?
    评论

报告相同问题?

问题事件

  • 系统已结题 12月1日
  • 已采纳回答 11月23日
  • 创建了问题 11月23日

悬赏问题

  • ¥15 c语言怎么用printf(“\b \b”)与getch()实现黑框里写入与删除?
  • ¥20 怎么用dlib库的算法识别小麦病虫害
  • ¥15 华为ensp模拟器中S5700交换机在配置过程中老是反复重启
  • ¥15 java写代码遇到问题,求帮助
  • ¥15 uniapp uview http 如何实现统一的请求异常信息提示?
  • ¥15 有了解d3和topogram.js库的吗?有偿请教
  • ¥100 任意维数的K均值聚类
  • ¥15 stamps做sbas-insar,时序沉降图怎么画
  • ¥15 买了个传感器,根据商家发的代码和步骤使用但是代码报错了不会改,有没有人可以看看
  • ¥15 关于#Java#的问题,如何解决?