洛谷_p2249_查找_用函数

洛谷 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
using namespace std;
typedef long long LL;

int main() {
	LL n, m;
	cin >> n >> m;
	vector arrya(n, 0);
	vector 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
*/

代码中注释的部分就是输入样例。

你可能感兴趣的:(算法,c++)