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),每两个整数之间用一个空格隔开。
第二行从小到大输入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……