这一题虽然是三级第一道编程题,但实际上它是一道最经典的"映射(Mapping)"问题,也是以后学习数组映射、哈希表、字符替换、密码替换等知识的重要基础。
🏰 GESP三级 编程题第一题
《密码王国——数字加密大冒险》
一、故事开始——神奇的密码本
1、很久很久以前,在数字王国里。
(1)有一天,国王宣布:
"从今天开始,所有数字都不能直接传送!"
(2)为什么?
因为坏人会偷看。
(3)于是,国王发明了一本神奇的——
📖《数字密码本》
2、里面写着:
0 → 9 1 → 0 2 → 1 3 → 2 4 → 3 5 → 4 6 → 5 7 → 6 8 → 7 9 → 83、意思就是:
看到0,就写成9。
看到1,就写成0。
看到2,就写成1。
……
每个数字,都有一个新的身份。
二、题目到底让我们干什么?
1、假设输入:
7表示:
有7个数字。
2、然后输入:
0 2 0 3 4 1 9最后输入密码本:
9 0 1 2 3 4 5 6 7 83、题目要求:
把原来的数字
全部变成新的数字。
三、我们一起手工模拟
1、原来的数字:
0查密码本:
0→9所以变成:
92、第二个数字:
2查密码本:
2→1得到
13、第三个:
0还是:
94、第四个:
3变成:
25、继续:
4→3 1→0 9→86、最后得到:
9 1 9 2 3 0 8是不是和样例完全一样?
四、密码本其实就是一个数组!
1、来看密码本:
9 0 1 2 3 4 5 6 7 82、我们把它放进数组。
keys[]里面。
数组的编号索引,就是数字。
下标索引 0 1 2 3 4 5 6 7 8 9数组里面放的是:
9 0 1 2 3 4 5 6 7 8画出来就是:
数字 0 ─────► 9 1 ─────► 0 2 ─────► 1 3 ─────► 2 4 ─────► 3 5 ─────► 4 6 ─────► 5 7 ─────► 6 8 ─────► 7 9 ─────► 8是不是特别像一本密码本?
3、数组下标,就是原来的数字!
(1)例如:
keys[0]得到:
9表示:
0→9(2)如果:
keys[4]得到:
3表示:
4→3(3)直接:
keys[数字]就能找到答案。
(4)这就是数组映射!
这是特别重要的思想!
五、程序是怎么工作的?
汉克老师带大家一步一步运行。
1、第一步
输入:
7程序知道:
共有7个数字2、第二步
输入:
0 2 0 3 4 1 9存进:
a[]里面。
3、现在:
a ↓ 0 2 0 3 4 1 94、第三步
(1)输入密码本:
9 0 1 2 3 4 5 6 7 8(2)存进:
keys[]里面。
(3)现在:
keys ↓ 9 0 1 2 3 4 5 6 7 85、第四步
开始一个一个输出。
(1)第一次:
a[0]里面是:
0于是:
keys[a[0]] ↓ keys[0] ↓ 9输出:
9(2)第二次:
a[1] = 2于是:
keys[2] = 1输出:
1(3)第三次:
a[2] = 0得到:
keys[0] = 9输出:
9……
一直到最后。
6、整个过程就是:
原数字 ↓ 作为数组下标 ↓ 查密码本 ↓ 输出新数字是不是特别简单?
七、完整代码
#include <iostream> using namespace std; int a[20010]; // 存放原来的数字 int keys[10]; // 密码本 int main() { int n; cin >> n; // 输入原来的数字 for(int i = 0; i < n; i++) { cin >> a[i]; } // 输入密码本 for(int i = 0; i < 10; i++) { cin >> keys[i]; } // 输出加密后的数字 for(int i = 0; i < n; i++) { cout << keys[a[i]] << " "; } cout << endl; return 0; }八、为什么这样写?
1、来看这一句:
cout << keys[a[i]];很多同学第一次看到都会发懵。
其实一点也不复杂。
2、例如:
i=3(1)那么:
a[3] = 4(2)于是:
keys[a[3]] ↓ keys[4] ↓ 3(3)所以输出:
33、可以把它理解成:
先从原数组里拿到数字,再把这个数字当作密码本的页码,翻到对应的一页,找到新的数字并输出。
因此:
keys[a[i]]4、其实就是两步:
(1)第一步
a[i]得到:
4(2)第二步
keys[4]得到:
3整个过程十分自然。
九、这道题真正考察什么?
1、很多同学觉得:
"老师,这不是一道数组题吗?"
2、其实,它真正考察的是一种非常重要的编程思想——映射(Mapping)。
所谓映射,就是建立一种"对应关系"。
3、例如:
学生编号 → 学生姓名 身份证号 → 身份信息 英文 → 中文 密码 → 原文 数字 → 新数字它们都有一个共同特点:
知道一个值,就能快速找到另一个对应的值。
4、在这道题中,就是:
原数字 ↓ keys[] ↓ 新数字以后学习map、unordered_map时,就是在做各种各样的"映射"。
十、本题知识总结
这道题虽然不难,但包含了三级考试中几个非常重要的知识点:
⭐数组存储数据:使用a[]保存原始数字,使用keys[]保存密码本。
⭐数组下标访问:利用keys[a[i]]快速查找对应关系。
⭐映射思想:用数组建立"原数字 → 新数字"的对应关系,这是后续学习哈希表、字符转换等内容的重要基础。
⭐顺序模拟:按照题目的要求,从左到右依次处理每一个数字,不遗漏、不跳步。
🌟 举一反三
学会了这道题,你已经能够解决很多类似的问题,例如:
🌈 字母替换(A→Z,B→Y……)
🌈 成绩等级转换(90→A,80→B……)
🌈 摩斯密码转换
🌈 DNA 碱基互补配对(A↔T,C↔G)
🌈 字符串加密与解密
🌈 哈希映射的基础应用
可以说,这是一道难度不高,但价值很高的基础题,真正掌握了它,以后遇到各种"查表替换"类题目都会迎刃而解。