相信你是最棒哒!!!
题目描述
输入 𝑛 个不超过 109的单调不减的(就是后面的数字不小于前面的数字)非负整数 𝑎1,𝑎2,…,𝑎𝑛,然后进行 𝑚 次询问。对于每次询问,给出一个整数 𝑞,要求输出这个数字在序列中第一次出现的编号,如果没有找到的话输出 −1 。
输入格式
第一行 2 个整数 𝑛 和 𝑚,表示数字个数和询问次数。
第二行 𝑛 个整数,表示这些待查询的数字。
第三行 𝑚 个整数,表示询问这些数字的编号,从 1 开始编号。
输出格式
输出一行,𝑚 个整数,以空格隔开,表示答案。
输入
11 3 1 3 3 3 5 7 9 11 13 15 15 1 3 6
输出
1 2 -1
说明/提示
数据保证,1≤𝑛≤106,0≤𝑎𝑖,𝑞≤109,1≤𝑚≤105
本题输入输出量较大,请使用较快的 IO 方式。
题目代码
注释版
#include<stdio.h>
int a[1000005]; // 定义一个整型数组a,大小为1000005,用于存储数据
int m, n; // 定义两个整型变量m和n,分别用于存储查询次数和数组a中元素的数量
// 二分查找函数,用于在数组a中查找元素x
int find(int x) {
int l = 1, r = n; // 初始化左右指针,l为左边界,r为右边界,这里数组是从1开始的,所以l初始化为1
while (l < r) { // 当左边界小于右边界时,进行循环
int mid = l + (r - l) / 2; // 计算中间位置的索引
if (a[mid] >= x) // 如果中间位置的元素大于等于x
r = mid; // 则将右边界更新为mid,因为x可能在mid的左边
else l = mid + 1; // 否则,将左边界更新为mid + 1,因为x可能在mid的右边
}
if (a[l] == x) // 如果左边界位置的元素等于x
return l; // 返回该位置的索引
else return -1; // 如果没有找到,返回-1
}
int main() // 主函数
{
int q; // 定义一个整型变量q,用于存储每次查询的值
scanf("%d%d", &n, &m); // 读取数组a中元素的数量n和查询次数m
for (int i = 1; i <= n; i++) // 循环读取数组a中的每个元素
scanf("%d", &a[i]); // 将输入的值存储到数组a的对应位置
for (int i = 1; i <= m; i++) { // 循环进行m次查询
scanf("%d", &q); // 读取每次查询的值
int ans = find(q); // 调用find函数查找q在数组a中的位置
printf("%d ", ans); // 输出查询结果
}
return 0;
}
简洁版
#include<stdio.h>
int a[1000005];
int m, n;
int find(int x) {
int l = 1, r = n;
while (l < r) {
int mid = l + (r - l) / 2;
if (a[mid] >= x)
r = mid;
else l = mid + 1;
}
if (a[l] == x)
return l;
else return -1;
}
int main()
{
int q;
scanf("%d%d", &n, &m);
for (int i = 1; i <= n; i++)
scanf("%d", &a[i]);
for (int i = 1; i <= m; i++) {
scanf("%d", &q);
int ans = find(q);
printf("%d ", ans);
}
return 0;
}
总结
这段代码的逻辑是:首先读取数列的大小和查询次数,然后读取数列中的每个元素并存储在数组中。接着,对于每次查询,使用二分查找算法在数组中查找对应的值,并输出查找结果。如果找到了值,则输出其在数组中的索引;如果没有找到,则输出-1。洛谷P2249