当前位置: 首页 > news >正文

CSP-J 2020 入门级 第一轮 阅读程序(1)

【题目】

CSP-J 2020 入门级 第一轮 阅读程序(1)

01 #include <cstdlib>
02 #include <iostream>
03 using namespace std;
04 
05 char encoder[26] = {'C','S','P',0};
06 char decoder[26];
07 
08 string st;
09 
10 int main()  {
11   int k = 0;
12   for (int i = 0; i < 26; ++i)
13     if (encoder[i] != 0) ++k;
14   for (char x ='A'; x <= 'Z'; ++x) {
15     bool flag = true;
16     for (int i = 0; i < 26; ++i)
17       if (encoder[i] ==x) {
18         flag = false;
19         break;
20       }
21       if (flag) {
22         encoder[k]= x;
23         ++k;
24       }
25   }
26   for (int i = 0; i < 26; ++i)
27      decoder[encoder[i]- 'A'] = i + 'A';
28   cin >> st;
29   for (int i = 0; i < st.length( ); ++i)
30      st[i] = decoder[st[i] -'A'];
31   cout << st;
32   return 0;
33 }

•判断题

  1. 输入的字符串应当只由大写字母组成,否则在访问数组时可能越界。( )
  2. 若输入的字符串不是空串,则输入的字符串与输出的字符串一定不一样。( )
  3. 将第 12 行的 i < 26 改为 i < 16,程序运行结果不会改变。( )
  4. 将第 26 行的 i < 26 改为 i < 16,程序运行结果不会改变。( )

•单选题

  1. 若输出的字符串为 ABCABCABCA,则下列说法正确的是( )。
    A. 输入的字符串中既有 S 又有 P
    B. 输入的字符串中既有 S 又有 B
    C. 输入的字符串中既有 A 又有 P
    D. 输入的字符串中既有 A 又有 B

  2. 若输出的字符串为 CSPCSPCSPCSP,则下列说法正确的是( )。
    A. 输入的字符串中既有 P 又有 K
    B. 输入的字符串中既有 J 又有 R
    C. 输入的字符串中既有 J 又有 K
    D. 输入的字符串中既有 P 又有 R

【题目考点】

1. 字符串
2. 映射关系

【解题思路】

05 char encoder[26] = {'C','S','P',0};
06 char decoder[26];
07 
08 string st;

首先看数组名字,encoder是加密器的意思,大概是通过该数组可以对字符串进行加密。decode是解密器的意思,大概是通过该数组可以将一个加密后的字符串解密。一个逻辑清晰、工整的代码的变量名都是有意义的,我们可以通过其名字推测它的实际作用。
已知encoder数值:encoder[0]:'C'encode[1]:'S'encode[2]:'P'

11   int k = 0;
12   for (int i = 0; i < 26; ++i)
13     if (encoder[i] != 0) ++k;

encoder下标范围为0到25,共26个位置。k为encoder数组中不为0的元素的数量,有encoder[0]~encoder[2]不为0,共3个元素,因此k的值为3。encode的下标从0开始,因此下标k是encoder数组最后一个元素的下一个位置,也是下一次要填充的元素的位置。

14   for (char x ='A'; x <= 'Z'; ++x) {
15     bool flag = true;
16     for (int i = 0; i < 26; ++i)
17       if (encoder[i] ==x) {
18         flag = false;
19         break;
20       }
21     if (flag) {
22       encoder[k]= x;
23       ++k;
24     }
25   }

字符型变量x从A循环到Z,对于每个x,遍历encoder数组,看是否存在一个元素的值为x:

  • 如果encoder中存在x,则将flag设为false,跳出循环。此处flag为true表示encoder中没有x,flag为false表示encoder中存在x。
  • 如果encoder中不存在x,则将x填充至encoder数组的末尾,k表示encoder数组中元素的个数,也是待填充元素的位置。

完成填充后,encoder数组为

下标iencoder[i]
0C
1S
2P
3A
4B
5D
6E
7F
8G
9H
10I
11J
12K
13L
14M
15N
16O
17Q
18R
19T
20U
21V
22W
23X
24Y
25Z
26   for (int i = 0; i < 26; ++i)
27      decoder[encoder[i]- 'A'] = i + 'A';

自然,这里的i是字母对应的数字,0对应A,1对应B,…,25对应Z。
此时decoder数组的值为i+'A'。该值是通过encoder[i]这个字符转成的编号在decoder数组中得到的。
结合encoder的意思是加密器,decoder的意思是解密器,该代码应该是完成了对字符的加密和解密的过程。
为方便理解:设原字符为i+'A',加密后的字符为j+'A'
那么有:encoder[i] = j+'A'
根据:decoder[encoder[i]-'A'] = decoder[j+'A'-'A'] = decoder[j] = i+'A'
所以有:decoder[j] = i+'A'

因此可以理解为:

  • 如果原字符为i+'A',那么加密后的字符为encoder[i] = j+'A'。使用encoder数组可以通过原字符找到加密后的字符。
  • 如果加密后的字符为j+'A',那么解密后的字符为decoder[j] = i+'A'。使用decoder数组可以通过加密后的字符找到原字符。

原字符和加密后的字符就是一组映射关系。根据encoder数组,把encoder数组的下标i变为字符i+'A',就能得到原字符和加密后的字符的对应关系。

原字符加密后的字符
AC
BS
CP
DA
EB
FD
GE
HF
IG
JH
KI
LJ
MK
NL
OM
PN
QO
RQ
SR
TT
UU
VV
WW
XX
YY
ZZ
28   cin >> st;
29   for (int i = 0; i < st.length( ); ++i)
30      st[i] = decoder[st[i] -'A'];
31   cout << st;

输入字符串st,将字符串st中每个字符通过decoder数组,从加密后的字符变为原字符,最后输出st。

整篇代码解决的问题是:
输入一个加密后的字符串,根据上述映射表找到每个加密后的字符对应的解密后的字符,完成对字符串的解密,最后输出解密后的字符串。

判断题
1. 输入的字符串应当只由大写字母组成,否则在访问数组时可能越界。( )
答:T
输入st后,有语句st[i] = decoder[st[i] -'A'];。当st[i]不是大写字母时,st[i]-'A'的值会小于0或大于25,会超出decoder数组的下标范围0~25,可能会发生数组越界。

2. 若输入的字符串不是空串,则输入的字符串与输出的字符串一定不一样。( )
答:F
观察映射表,对于字母TUVWXYZ,原字符和加密后的字符是相同的。对于完全由这几个字母组成的加密后的字符串,解密后的字符串与加密后的字符串也是相同的。比如输入“TUVWXYZ”,就会输出“TUVWXYZ”。输入的字符串与输出的字符串可能一样。

3. 将第 12 行的 i < 26 改为 i < 16,程序运行结果不会改变。( )
答:T

12   for (int i = 0; i < 26; ++i)
13     if (encoder[i] != 0) ++k;

第12行和第13行的作用的统计k的值,k的值指的是encoder数组中已有元素的数量。
根据

05 char encoder[26] = {'C','S','P',0};

可知,encoder数组中已有3个元素。第12、13行运行时,只有在i位0、1、2时,encoder[i]不为0,k会增加1。在i大于等于3的情况下,encoder[i]都为0,k不会增加。
当i循环到3时,k已经为3了。i无论是循环到15还是25,k的值都为3,没有区别。
因此当第12行for循环第二个表达式改为i < 16时,结果不变。

4. 将第 26 行的 i < 26 改为 i < 16,程序运行结果不会改变。( )
答:F

26   for (int i = 0; i < 26; ++i)
27      decoder[encoder[i]- 'A'] = i + 'A';

第26~27行完成的对decoder数组的设置。
如果i只循环到15,那么decoder[16]~decoder[25]都为0。
对于原字符i+'A',假设加密后的字符为encoder[i] = j+'A'
i >= 16时,没有设置decoder[j] = i+'A'。因此对于i >= 16的情况,无法通过decoder[encoder[i]-'A']得到加密后的字符j+'A'对应的原字符i+'A'。会导致一些字符无法正确解码,无法正常输出。因此该题选“错误”。

比如将第 26 行的 i < 26 改为 i < 16。已知encoder[25]='Z',那么就没有当i为25时设置decoder[encoder[25]-'A'] = decoder[25] = 25+'A' = 'Z'。而是保持decoder[25] = '\0'。当输入的加密后的字符串st中存在Z时,无法将Z解密为Z,而是解密为\0,导致该字符无法输出。

•单选题

5. 若输出的字符串为 ABCABCABCA,则下列说法正确的是( )。
A. 输入的字符串中既有 S 又有 P
B. 输入的字符串中既有 S 又有 B
C. 输入的字符串中既有 A 又有 P
D. 输入的字符串中既有 A 又有 B

答:A
输入的字符串为加密后的字符串,输出的字符串为原字符串。给输出字符串,询问输入字符串的请,进行的就是加密的过程。
对字符"ABCABCABCA"加密,观察上述映射表,A加密为C,B加密为S,C加密为P,因此加密后的字符串,也就是输入字符串为"CSPCSPCSPC"。
该字符串中既有S又有P,选A。

6. 若输出的字符串为 CSPCSPCSPCSP,则下列说法正确的是( )。
A. 输入的字符串中既有 P 又有 K
B. 输入的字符串中既有 J 又有 R
C. 输入的字符串中既有 J 又有 K
D. 输入的字符串中既有 P 又有 R

答:D
输入的字符串为加密后的字符串,输出的字符串为原字符串。给输出字符串,询问输入字符串的请,进行的就是加密的过程。
对字符"CSPCSPCSPCSP"加密,观察上述映射表,C加密为P,S加密为R,P加密为N,因此加密后的字符串,也就是输入字符串为PRNPRNPRNPRN"。. 输入的字符串中既有 P 又有 R。因此选D。

【答案】

  1. T
  2. F
  3. T
  4. F
  5. A
  6. D

相关文章:

  • 线程运行的现象和相关指令
  • python训练营day50
  • 工作总结及记录
  • 中兴B860AV1.1强力降级固件包
  • 无人设备遥控器之无线电控制技术篇
  • 大疆相机元数据说明
  • 解码成都国际数字影像产业园产城融合新发展路径
  • 【IC】Genus怎么写出scanDEF?
  • 【LangChain】2 储存
  • 三星手机Galaxy S24 Ultra使用adb工具关闭和开启系统更新
  • 小白学Pinia状态管理
  • 撤销Git合并操作方法总结
  • AI Engine Kernel and Graph Programming--知识分享9
  • 卷积神经网络(一)
  • JVM面试基础篇
  • 界面控件Kendo UI在实战应用——打通数据链路,重塑业务效率
  • leetcode0684. 冗余连接-medium
  • 3 Studying《深入理解Android卷(邓凡平)》1
  • [特殊字符] React 与 Vue 源码级对比:5大核心差异与实战选择指南
  • 盒模型小全
  • 浙江五联建设有限公司网站/深圳百度推广客服电话多少
  • 360建筑网忘记密码怎么办/成都关键词优化平台
  • 做网站直接从网上的icon吗/推广文章的步骤
  • 做网站要多少像素/seo关键技术有哪些
  • 建设的比较好的档案馆网站/软件开发公司简介
  • wordpress读取文件内容/广州网站优化