文章目录
一、P2249 【深基13.例1】查找
1.题目描述
输入 n个单调不减的(就是后面的数不小于前面的数字)非负整数,然后进行 m 次询问。对于每次询问,给出一个整数q,要求输出这个数字在序列中第一次出现的编号,如果没有找到的话输出 -1 。
2.输入格式
第一行 2 个整数 n 和 m,表示数字个数和询问次数。
第二行 n 个整数,表示这些待查询的数字。
第三行 m 个整数,表示询问这些数字的编号,从 1 开始编号。
3.输出格式
m 个整数表示答案。
4.输入输出样例
> 输入:
11 3
1 3 3 3 5 7 9 11 13 15 15
1 3 6
> 输出:
1 2 -1
5.做题思路
这是一道比较简单的二分法应用题,在看到有序数组时就应该想到需要使用二分法,这道题的主要特点应该就是有序数组中会出现多个相同数据.
所以就需要在写二分法的时候把这个给考虑进去,就算找到的中值等于了目标值,也并不代表该中值为答案,可能中值前面的数和它时一样的,所以需要继续往前搜寻。
6.代码
#include <stdio.h>
#include <stdlib.h>
int Found(int* p, int flag, int head, int end);
#define N 1000000
#define M 100000
int a[N], b[M];
int main()
{
int n, m;
scanf_s("%d %d", &n, &m); /* 输入数字个数n和询问次数m */
for (int i = 0; i < n; i++) /* 输入数字 */
scanf_s("%d", &a[i]);
for (int i = 0; i < m; i++)
{
scanf_s("%d", &b[i]); /* 输入查询的数字 */
printf("%d ", Found(a, b[i], 0, n - 1)); /* 输出二分法函数返回值即为答案 */
}
return 0;
}
int Found(int* p, int flag, int head, int end) /* 定义二分法使用函数 */
{
int mid = 0;
while (head < end) /* 二分法主体 */
{
mid = (head + end) / 2;
if (flag <= p[mid]) end = mid;
else head = mid + 1;
}
if (flag == p[head]) return head + 1; /* 如果满足条件,则说明找到该数字 */
else return -1; /* 否则输出-1 */
}
二、P1914 凯撒密码
1.题目描述
密码是由原文字符串(由不超过 50 个小写字母组成)中每个字母向后移动 n (0≤n≤26)位形成的。z 的下一个字母是 a,如此循环。他现在找到了移动前的原文字符串及 n,请你求出密码。
2.输入格式
第一行:n。第二行:未移动前的一串字母
3.输出格式
一行,是此密码
4.输入输出样例
> 输入:
1
qwe
> 输出:
rxf
5.做题思路
刚看到这道题的时候直接就写了,觉得应该一次就过了,但是测试的时候出了错误答案,当时就有些纳闷,仔细看了会才发现这道题的高深之处
‘z’的值是122,计算机中1个字符占1个字节,也就是8位,其大小最大为2^7 - 1=127,如果给’z’向后移5位以上,它的值就会溢出,导致最后的结果错误,为了解决这个问题,需要先把字符的值缩小,保证在’z’+26时不会溢出,最后重置后,再把值放大。
6.代码
#include <stdio.h>
#include <stdlib.h>
int main()
{
char ch[50];
int n, i = 0;
scanf_s("%d", &n); /* 输入位移量n */
scanf_s("%s", ch, 50); /* 输入该字符串 */
while (ch[i] != '\0') /* 读取整个字符串 */
{
ch[i] -= 'a' - 1 - n; /* 将字符的值先缩小,防止溢出 */
if (ch[i] > 26) ch[i] -= 26; /* 将超出'z'值的字母从头开始,即'z'+ 1='a' */
ch[i] += 'a' - 1; /* 再将字符放大为原来的值 */
i++; /* 继续读取下一个字符 */
}
printf("%s", ch);
return 0;
}
- 在洛谷测试需要修改scanf_s函数,上述代码在VS2019中可正常运行,如果不修改上述函数,可能会编译错误。
- scanf_s在读入字符时需要填写第三个形参,填写内容是读入字符的最大长度。即上述《凯撒密码》中的scanf_s("%s", ch, 50),即最长读入字符串为50。