






这一题虽然是三级第一道编程题,但实际上它是一道最经典的"映射(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 → 8
3、意思就是:
看到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 8
3、题目要求:
把原来的数字
全部变成新的数字。
三、我们一起手工模拟
1、原来的数字:
0
查密码本:
0→9
所以变成:
9
2、第二个数字:
2
查密码本:
2→1
得到
1
3、第三个:
0
还是:
9
4、第四个:
3
变成:
2
5、继续:
4→3
1→0
9→8
6、最后得到:
9 1 9 2 3 0 8
是不是和样例完全一样?
四、密码本其实就是一个数组!
1、来看密码本:
9 0 1 2 3 4 5 6 7 8
2、我们把它放进数组。
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
9
4、第三步
(1)输入密码本:
9 0 1 2 3 4 5 6 7 8
(2)存进:
keys[]
里面。
(3)现在:
keys
↓
9
0
1
2
3
4
5
6
7
8
5、第四步
开始一个一个输出。
(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)所以输出:
3
3、可以把它理解成:
先从原数组里拿到数字,再把这个数字当作密码本的页码,翻到对应的一页,找到新的数字并输出。
因此:
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)
-
🌈 字符串加密与解密
-
🌈 哈希映射的基础应用
可以说,这是一道难度不高,但价值很高的基础题,真正掌握了它,以后遇到各种"查表替换"类题目都会迎刃而解。