给出有n个元素的由小到大的序列,请你编程找出每次询问的某元素第一次出现的位置,共询问m次。(n<=2,000,000,m<=100,000,序列中的数值均小于105) 输入格式: 一个整数n,表示由小到大序列元素个数; 第二行有n个整数; 第三行一个整数,表示询问的次数m; 接着有m行,每行一个整数x,表示待查找的元素; 输出格式: 针对每次询问,如果x在序列中,则输出x第一次出现的位置,否则输出-1。 每个询问单独输出一行。
时间: 2024-03-23 19:41:01 浏览: 114
一个免费的c++小游戏集合
5星 · 资源好评率100%
这道题可以使用二分查找来解决。
首先对原序列进行预处理,使用一个数组 `pos` 记录每个元素第一次出现的位置。然后对于每个询问的元素,使用二分查找找到它在序列中第一次出现的位置即可。
以下是示例代码:
```python
n = int(input())
a = list(map(int, input().split()))
m = int(input())
pos = [-1] * (max(a) + 1)
# 预处理
for i in range(n):
if pos[a[i]] == -1:
pos[a[i]] = i
# 二分查找
for i in range(m):
x = int(input())
l, r = 0, n - 1
while l < r:
mid = (l + r) // 2
if a[mid] < x:
l = mid + 1
else:
r = mid
if a[l] == x:
print(pos[x])
else:
print(-1)
```
其中,`pos` 数组表示每个元素第一次出现的位置,初始化为 `-1`。在预处理中,我们遍历原序列,对于每个元素,如果它第一次出现,则记录它的位置。
在二分查找中,我们将序列分为左右两部分,如果中间元素小于待查找元素,则在右半部分查找;否则在左半部分查找。最后,如果找到了待查找元素,则输出它第一次出现的位置;否则输出 `-1`。
以下是使用 C 语言编写的程序:
```c
#include <stdio.h>
int main() {
int n, m, i, x, l, r, mid;
int a[2000000], pos[100001] = {-1};
// 输入序列
scanf("%d", &n);
for (i = 0; i < n; i++) {
scanf("%d", &a[i]);
if (pos[a[i]] == -1) pos[a[i]] = i;
}
// 二分查找
scanf("%d", &m);
for (i = 0; i < m; i++) {
scanf("%d", &x);
l = 0, r = n - 1;
while (l < r) {
mid = (l + r) / 2;
if (a[mid] < x) l = mid + 1;
else r = mid;
}
if (a[l] == x) printf("%d\n", pos[x]);
else printf("-1\n");
}
return 0;
}
```
和 Python 版本的程序类似,C 语言版本的程序也是先预处理得到每个元素第一次出现的位置,然后使用二分查找来查找待查找元素第一次出现的位置。注意,由于 C 语言数组下标从 0 开始,因此需要将 `pos` 数组初始化为 `-1`,而不是 0。
阅读全文