数的范围(二分)
题目要求
给定一个按照升序排列的长度为 n 的整数数组,以及 q个查询。
对于每个查询,返回一个元素 k的起始位置和终止位置(位置从 0 开始计数)。
如果数组中不存在该元素,则返回 -1 -1。
输入格式
第一行包含整数 n 和 q,表示数组长度和询问个数。
第二行包含 n 个整数(均在 1∼10000 范围内),表示完整数组。
接下来 q 行,每行包含一个整数 k,表示一个询问元素。
输出格式
共 q 行,每行包含两个整数,表示所求元素的起始位置和终止位置。
如果数组中不存在该元素,则返回 -1 -1。
数据范围
1≤n≤100000
1≤q≤10000
1≤k≤10000
输入样例:
6 3
1 2 2 3 3 4
3
4
5
输出样例:
3 4
5 5
-1 -1
实例答案
#include<iostream>
#include<algorithm>
#include<string>
#include<math.h>
using namespace std;
const int N = 1e6 + 10;
int arr[N];//arr用来储存数组元素
int n, q;//n为数组的大小,q为要询问的次数
int k;//k为每次询问的值
int left_check(int l, int r)//从左向右找第一个与k相等的坐标
{
while (l < r)
{
int mid = l + r >> 1;
if (arr[mid] >= k) r = mid;
else l = mid + 1;
}
return l;
}
int right_check(int l, int r)//从右向左找第一个与k相等的坐标
{
while (l < r)
{
int mid = l + r + 1 >> 1;
if (arr[mid] <= k) l = mid;
else r = mid - 1;
}
return l;
}
int main()
{
scanf("%d%d", &n, &q);
for (int i = 0; i < n; i++)
{
scanf("%d", &arr[i]);
}
while (q--)
{
scanf("%d", &k);
int d = left_check(0, n - 1);
if (arr[d] != k) cout << "-1 -1";//如果不等于k则表示不存在
else
{
cout << d << " ";
d = right_check(0, n - 1);
cout << d << endl;
}
}
return 0;
}

浙公网安备 33010602011771号