洛谷 P2249 【深基13.例1】查找
这个暴力解法还是蛮好想的。
对于每个询问,从头到尾搜一遍,找到就输出并 break ,如果一直找不到最后输出 −1
其实也可以用另一种方法:
正确且符合入门级别的解决策略:二分查找
当然,二分方法也是极好的
那么为什么要用二分查找呢?//当然是看标签了//
其实呢,原因有两个:
1.效率比较高,时间复杂度低;
2.这道题避开了其劣势:需要查找的序列必须为有序序列;而本题中的序列恰好单调不减。
二分只是差一嘴,咱们回到正题。
首先找到这串数字中间位置的那个数,然后与需要查询的数比较
如果要查询的数小于中间那个数,那么答案肯定在左边
如果要查询的数大于中间那个数,那么答案肯定在右边
如果等于的话继续在左边找,因为找到的位置还不能确定是第一个数
如此重复,直到要查询的区域变为1。
auto lw = lower_bound(arrya.begin(), arrya.end(), arryb[i]);从arry.begin()到arrya.end()区间内查找arryb[i],如果找到了,返回一个指针,如果没找到,返回第一个比它大的值的指针,这也是整个代码最重要的部分。
(代码在后面)。
for (LL i = 0; i < m; i++) {
auto lw = lower_bound(arrya.begin(), arrya.end(), arryb[i]);
if (lw == arrya.end() || (*lw) != arryb[i]) {
cout << -1 << ' ';
} else {
cout << ((lw - arrya.begin()) + 1) << ' ';
}
}
请个代码中,我并没有做排序。因为洛谷里边的,输入样例已经帮你排好序了,所以呢,要排序了的代码如下。
sort(arrya.begin(),arrya.end());
下面是完整的代码
#include<bits/stdc++.h>
using namespace std;
typedef long long LL;
int main() {
LL n, m;
cin >> n >> m;
vector<LL> arrya(n, 0);
vector<LL> arryb(m, 0);
for (LL i = 0; i < n; i++) {
cin >> arrya[i];
}
for (LL i = 0; i < m; i++) {
cin >> arryb[i];
}
for (LL i = 0; i < m; i++) {
auto lw = lower_bound(arrya.begin(), arrya.end(), arryb[i]);
if (lw == arrya.end() || (*lw) != arryb[i]) {
cout << -1 << ' ';
} else {
cout << ((lw - arrya.begin()) + 1) << ' ';
}
}
return 0;
}
/*
11 3
1 3 3 3 5 7 9 11 13 15 15
1 3 6
*/
代码中注释的部分就是输入样例。
1416

被折叠的 条评论
为什么被折叠?



