GESP2026年6月认证C++三级( 第三部分编程题(1、加密))精讲








这一题虽然是三级第一道编程题,但实际上它是一道最经典的"映射(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[]
      ↓
    新数字

以后学习 mapunordered_map 时,就是在做各种各样的"映射"。


十、本题知识总结

这道题虽然不难,但包含了三级考试中几个非常重要的知识点:

数组存储数据 :使用 a[] 保存原始数字,使用 keys[] 保存密码本。

数组下标访问 :利用 keys[a[i]] 快速查找对应关系。

映射思想 :用数组建立"原数字 → 新数字"的对应关系,这是后续学习哈希表、字符转换等内容的重要基础。

顺序模拟:按照题目的要求,从左到右依次处理每一个数字,不遗漏、不跳步。


🌟 举一反三

学会了这道题,你已经能够解决很多类似的问题,例如:

  • 🌈 字母替换(A→Z,B→Y......)

  • 🌈 成绩等级转换(90→A,80→B......)

  • 🌈 摩斯密码转换

  • 🌈 DNA 碱基互补配对(A↔T,C↔G)

  • 🌈 字符串加密与解密

  • 🌈 哈希映射的基础应用

可以说,这是一道难度不高,但价值很高的基础题,真正掌握了它,以后遇到各种"查表替换"类题目都会迎刃而解。