欢迎您访问 最编程 本站为您分享编程语言代码,编程技术文章!
您现在的位置是: 首页

你还不知道的两点解题奇技有哪些?-问题介绍

最编程 2024-10-07 13:18:25
...

给定一个按照升序排列的长度为 n 的整数数组,以及 q 个查询。

对于每个查询,返回一个元素 k 的起始位置和终止位置(位置从 0 开始计数)。

如果数组中不存在该元素,则返回 -1 -1

输入格式:

第一行包含整数 nq,表示数组长度和询问个数。

第二行包含 n 个整数(均在 1∼10000 范围内),表示完整数组。

接下来 q 行,每行包含一个整数 k,表示一个询问元素。

输出格式:
q 行,每行包含两个整数,表示所求元素的起始位置和终止位置。

如果数组中不存在该元素,则返回 -1 -1

数据范围:

1 ≤ n ≤ 100000 {1≤n≤100000} 1n100000

1 ≤ q ≤ 10000 {1≤q≤10000} 1q10000

1 ≤ k ≤ 10000 {1≤k≤10000} 1k10000

输入样例:

6 3
1 2 2 3 3 4
3
4
5

输出样例:

3 4
5 5
-1 -1

这道题目是二分的一个经典题目,我们使用二分的板子就可以解决。下面是我的代码。

#include <iostream>
#include <cstring>
#include <algorithm>

using namespace std;
const int N = 1e5 + 10;

typedef long long LL;
int n, q;
int num[N];

int main() {
	ios::sync_with_stdio(false),cin.tie(0),cout.tie(0);
	cin >> n >> q;
	for (int i = 0; i < n; i ++) cin >> num[i];

	while(q --) {
		int target;
		cin >> target;
		int l = 0, r = n - 1;
		while(l < r) {
			int mid = (l + r) >> 1;
			if(num[mid] < target) l = mid + 1;
			else r = mid;
		}
		if (num[l] != target) {
			cout << -1 << " " << -1 << endl;
		} else {
			cout << l << " ";
			r = n - 1;
			while(l < r) {
				int mid = (l + r + 1) >> 1;
				if(num[mid] > target) r = mid - 1;
				else l = mid;
			}
			cout << l << endl;
		    }
		}
	return 0;
}