C++-找数(标准二分) 解题思路

【Horn Studio】编程专栏: 找数 解题思路

题目

题目描述

给定 N个整数和 K个待查找的整数M1,M2,...,MK。如果待查找的整数在给定的 N 个整数中,请输出待查找的整数是数组中第几个元素(从 1 开始计算,第一个元素计 1 而不是 0);如果待查找的整数不在给定的 N个整数中,则输出 0。
 

输入

第一行输入两个整数 N(1≤N≤10^6)和 K(1≤M≤10^6),分别表示给定的整数总个数和待查找的数的个数;
第二行从小到大输入N 个整数 Number(1≤Numberi≤10^6,其中1≤i≤N),每两个整数之间用一个空格隔开;
第三行输入K个整数Numberj(1≤Numberj≤10^6,其中 1≤j≤K),每两个整数之间用一个空格隔开。
 

输出

输出为一行,包括 K个部分,每个部分为题目描述中待查找的元素索引或 0,K个部分之间用一个空格分隔。输出行尾不含多余空格。
 

样例输入 复制

3 1
1 4 6
4

样例输出 复制

2

提示

保证N个整数互不相同

来源

思路

 

原来是二分,这种算法要比枚举更省空间,也更加的省时间,一举两得,妙已!

不过在此之前得先了解一下二分算法究竟是何方神圣……

二分法,即二分搜索法,是通过不断缩小解可能存在的范围,从而求得问题最优解的方法。例如,如果一个序列是有序的,那么可以通过二分的方法快速找到所需要查找的元素,相比线性搜索要快不少。此外二分法还能高效的解决一些单调性判定的问题。二分法的时间复杂度为O(logn),可以说是算小的了。

 

这道题他没有说是不是有序的,我们需要sort一下……但是题库有水分100L,我忘记加了还是AC,太奇怪了……这并无妨。我们需要加一个结构体存储原本的下标,这样就可以万无一失了,主要怎么写呢……自己想!

代码

#include <bits/stdc++.h>
using namespace std;
int n, m;
int a[1000001];
 
int main()
{
    scanf("%d%d", &n, &m);
    for (int i = 0; i < n; i++) {
        scanf("%d", &a[i]);
    }
    while (m--) {
        int k;
        scanf("%d",&k);
        int low = 0, high = n - 1, mid;
        int res = -1;
        while (low <= high) {
            mid = (low + high) / 2;
            if (k == a[mid]) {
                res = mid;
                break;
            } else if (k < a[mid]) {
                high = mid - 1;
            } else {
                low = mid + 1;
            }
        }
        printf("%d\n",res+1);
    }
    return 0;
}

彩蛋

据说有一个老师是学习Java的,自己学习一天就从hello world学到了dp……

posted @ 2022-04-30 21:31  冯子坤  阅读(267)  评论(0编辑  收藏  举报