蓝桥杯·全国青少年信息素养大赛·电子学会Python/C/C++考级:任意进制互转与大数多进制加法解析

蓝桥杯的填空题、电子学会 C/C++ 考级的算法题、全国青少年信息素养大赛的算法应用赛项,都特别喜欢考「进制转换」------给你一个超长的大数,让你在二进制、八进制、十六进制之间互转,或者让两个不同进制的数相加。这类题看着简单,却藏着字符映射、大数溢出、进位遗忘等一堆坑。今天我们用一道原创题「校园密码学社的进制密信」,把任意 2~36 进制互转和「大数多进制加法」一次讲透,并给出 C++ / Python 双版本与完整考点拆解。

一、题目与项目目标

原创题:校园密码学社的进制密信

社团用一种进制来加密消息。给定:

  • 一个由数字 0-9 和大写字母 A-Z(代表 10~35)组成的字符串 s,表示 k 进制下的一个非负整数(2 ≤ k ≤ 36);

  • 一个目标进制 b(2 ≤ b ≤ 36)。

请完成两件事:

  1. 基础任务 :把 s 从 k 进制转换为 b 进制字符串输出(同样用 0-9/A-Z 表示)。

  2. 进阶任务 :再给定另一个 k 进制字符串 t,求 s + t 的和,并以 k 进制字符串输出(注意:两个数可能极长,几百位,普通整数类型装不下)。

样例:

  • 输入 s="FF", k=16, b=2 → 输出 11111111

  • 输入 s="1010", k=2, b=16 → 输出 A

  • 输入 s="F", t="1", k=16 → 进阶输出 10

  • 输入 s="A", t="A", k=16 → 进阶输出 14

二、核心考点

  1. 进制本质 :一个 k 进制串 d[n-1]...d[0] 的值 = Σ di·k^i。
  2. 字符 ↔ 数值映射 :'0'~'9' → 0~9;'A'~'Z' → 10~35。写反是最高频笔误。
  3. 大数表示 :几百位的数字必须用字符串 存储,不能先转成 int / long long,否则必然溢出。
  4. 辗转取余 + 逆序收集 :十进制大数转 b 进制,靠「反复除以 b 取余」,余数从低位到高位,最后整体反转。
  5. 按位加法 + 进位:多进制加法直接对齐末位、逐位相加并进位,比「先转十进制再加」更优雅也更通用。

三、解法拆解

3.1 思路总览

  • k 进制 → b 进制:因为进制不同,最稳妥的中间桥梁是「十进制」。
  • 第一步:把 k 进制串 s 用「乘 k 累加」的方式,变成十进制大数字符串(一个能装下任意位数的十进制串)。
  • 第二步:把十进制大数字符串用「反复除以 b 取余」变成 b 进制串。
  • 两个 k 进制大数相加 :直接对齐末位逐位加,维护进位 carry,循环条件带上 || carry,最后反转。

3.2 C++ 版本(字符串大数,杜绝溢出)

cpp 复制代码
#include <bits/stdc++.h>
using namespace std;

int val(char c) {
    if (c >= '0' && c <= '9') return c - '0';
    return toupper(c) - 'A' + 10;   // 10~35 用 A~Z
}
char chr(int v) {
    if (v < 10) return '0' + v;
    return 'A' + (v - 10);
}

// 十进制大数字符串 = 原十进制串 * k + 一位 digit
string mulAdd(const string& dec, int k, int digit) {
    string res;
    int carry = digit;
    for (int i = (int)dec.size() - 1; i >= 0; --i) {
        int cur = (dec[i] - '0') * k + carry;
        carry = cur / 10;
        res.push_back((cur % 10) + '0');
    }
    while (carry) { res.push_back((carry % 10) + '0'); carry /= 10; }
    reverse(res.begin(), res.end());
    return res;
}

// k 进制串 -> 十进制字符串(大数,避免 long long 溢出)
string toBase10(const string& s, int k) {
    string dec = "0";
    for (char c : s) dec = mulAdd(dec, k, val(c));
    return dec;
}

// 十进制字符串 -> b 进制字符串(对十进制大数反复除 b 取余)
string base10ToB(string dec, int b) {
    if (dec == "0") return "0";
    string res;
    while (dec != "0") {
        int rem = 0;
        string quo;
        for (char c : dec) {
            int cur = rem * 10 + (c - '0');
            quo.push_back((cur / b) + '0');
            rem = cur % b;
        }
        size_t p = quo.find_first_not_of('0');
        dec = (p == string::npos) ? "0" : quo.substr(p);
        res.push_back(chr(rem));
    }
    reverse(res.begin(), res.end());
    return res;
}

// 组合:k 进制 -> b 进制
string kToB(const string& s, int k, int b) {
    return base10ToB(toBase10(s, k), b);
}

// 进阶:两个 k 进制大数直接按位相加(推荐,不依赖十进制中间表示)
string addBaseK(string a, string b, int k) {
    // 先去掉输入的前导零,避免把「占位 0」当有效数字参与进位
    auto strip = [](string& x) {
        size_t p = x.find_first_not_of('0');
        if (p == string::npos) x = "0";   // 全 0 时保留一个 0
        else x = x.substr(p);
    };
    strip(a); strip(b);
    string res;
    int i = (int)a.size() - 1, j = (int)b.size() - 1, carry = 0;
    while (i >= 0 || j >= 0 || carry) {
        int x = (i >= 0) ? val(a[i--]) : 0;
        int y = (j >= 0) ? val(b[j--]) : 0;
        int s = x + y + carry;
        carry = s / k;
        res.push_back(chr(s % k));
    }
    reverse(res.begin(), res.end());
    return res;
}

int main() {
    cout << kToB("FF", 16, 2) << "\n";     // 11111111
    cout << kToB("1010", 2, 16) << "\n";   // A
    cout << addBaseK("F", "1", 16) << "\n"; // 10
    cout << addBaseK("A", "A", 16) << "\n"; // 14
    return 0;
}

3.3 Python 版本(利用无限精度整数,极简)

python 复制代码
def val(c):
    return int(c) if c.isdigit() else ord(c.upper()) - ord('A') + 10
def chr_(v):
    return str(v) if v < 10 else chr(ord('A') + v - 10)

def dec_to_base(n, b):
    if n == 0:
        return "0"
    res = []
    while n > 0:
        res.append(chr_(n % b))
        n //= b
    return ''.join(reversed(res))

def k_to_b(s, k, b):
    return dec_to_base(int(s, k), b)   # Python 整型无上限,超大数也稳

def add_basek(a, b, k):
    return dec_to_base(int(a, k) + int(b, k), k)

print(k_to_b("FF", 16, 2))     # 11111111
print(k_to_b("1010", 2, 16))   # A
print(add_basek("F", "1", 16))  # 10
print(add_basek("A", "A", 16))  # 14

注意:Python 的 int(s, k) 能直接把 k 进制串转成无限精度整数,所以转换和加法都能「一行搞定」。但蓝桥杯 / 电子学会考级往往要求你手写转换过程,所以 C++ 版的「字符串大数」思路才是真正要掌握的考点。

四、时间 / 空间复杂度

  • toBase10 :输入长 L,十进制串长约 L·log₁₀k,每位做一遍 mulAdd(长度 O(L·logk)),整体约 O(L²·logk)。
  • base10ToB :十进制串长 D≈L·log₁₀k,每次除以 b 扫描整串 O(D),共 D 次,约 O(D²)=O(L²·log²k)。
  • kToB 组合 :O(L²·log²k),足以应付题目里几百位的输入。
  • addBaseK :仅 O(max(|a|, |b|)),线性扫描,非常高效。
  • 空间 :均只用到与输入长度同阶的临时字符串,O(L)。

五、六大易错点

  1. 字母大小写 :输入可能混用 a-f,务必 toupper 后再映射;输出统一用大写 A-Z。
  2. 字符与数值写反 :val('A')=10 不是 1;chr(10)='A'。写反结果全错。
  3. 进制上界 36:超过 36 需要更多字符(如小写字母),题目限定 2~36,别越界访问数组。
  4. 余数要逆序 :「除 b 取余」得到的是从低位到高位,最后一定 reverse 一次,否则得到反序答案。
  5. long long 溢出 :几百位的数字绝不能 先 stoi/stoll 转成整数,必须用字符串大数。这是本题最大的坑。
  6. 进位漏加 :addBaseK 的循环条件要带 || carry,否则最高位产生的进位会被丢掉,结果少一位。
  7. 输入前导零 :若输入串本身带前导 0(如 0023),必须先在加法里把前导零规范化,否则会把这个「占位 0」当有效数字参与进位,导致结果凭空多一位前导 0。

六、进阶拓展

  • 大数多进制乘法:与加法同理,按位相乘累加、维护进位,可拓展到任意进制大数乘法。
  • 负进制转换 :如 -2 进制,要求余数始终落在 [0, |b|-1],取余后要「修正」到非负区间,是蓝桥杯偏难怪题。
  • 浮点进制 :小数部分用「乘 b 取整」不断生成小数位,处理循环节。
  • 与高精度结合:C++ 版我们正是用十进制字符串模拟「乘加 / 除法」,这正是高精度算法的核心思想,理解了它,高精度加减乘除都能触类旁通。
  • 真题风格 :蓝桥杯填空常给一个超长数让你转成某进制输出,或让两个二进制 / 十六进制数相加,本质就是上面的 kToB 与 addBaseK。

七、小结与互动

进制转换的本质只有一句话:位权展开 + 辗转取余 + 逆序收集 ;大数场景则用字符串模拟运算避免溢出。把 kToB 和 addBaseK 两个函数记熟,蓝桥杯、电子学会 C/C++ 考级、信息素养大赛的进制题基本都能直接套。

练手留言区 :试试用 addBaseK 计算 s="1Z", t="1", k=36 的结果是多少?(提示:Z 是 35)欢迎在评论区写下你的答案,也欢迎分享你遇到过的进制转换奇葩坑。


📚 免费少儿编程资料(夸克网盘领取)

以下资料来自夸克网盘分享,点击链接可直接保存;若需在 App 内打开,也可复制下方明文链接:

  1. 全国青少年信息素养大赛复赛集训题目Python&C++.docx
    https://pan.quark.cn/s/93995d3cb150
  2. 2024信息素养-智能算法应用挑战赛-复赛初中组题目7月7日.pdf
    https://pan.quark.cn/s/da97b5dbf75d
  3. Python背记手册.pdf
    https://pan.quark.cn/s/7568ae9ca92b
  4. Python课程
    https://pan.quark.cn/s/a94bf02d00c6
  5. 2024信息素养大赛图形化复赛集训题答案3-9
    https://pan.quark.cn/s/6ccab7ec3cbc
  6. 2025年03月份电子学会考级真题
    https://pan.quark.cn/s/4403c4228912
  7. 2025全国青少年信息素养大赛赛项说明
    https://pan.quark.cn/s/d9d0df4a9f29
  8. 青少儿信息素养大赛编程资料
    https://pan.quark.cn/s/4ab6bd83be8a

资料持续更新,关注获取最新分享。

相关推荐
再__努力1点2 小时前
一个开源的AI边缘计算平台:一个项目把算能、瑞芯微、x86的NPU全打通了
人工智能·python·课程设计·媒体·流媒体
小oo呆2 小时前
【学习心得】Python函数参数中的两个特殊分隔符
开发语言·python
x10n92 小时前
微软 VC++ 运行库合集VCRedistPack
开发语言·c++·microsoft·vc++运行库·dll报错
qz_Serene2 小时前
C++:string(底层,常用接口,具体题目,模拟实现)
开发语言·c++
SEO_juper2 小时前
AI 爬虫 robots.txt 检查工具:你的站是不是把 AI 挡在门外了
开发语言·人工智能·爬虫·python·外贸独立站
碧海银沙音频科技研究院2 小时前
基于ATS308X的无线语音交互对话功能实现
人工智能·嵌入式硬件·深度学习·算法
看我debug3 小时前
Android 运行时分析工作台 (Demo)。统一管理 Frida 脚本、自动注入(修改运行时代码)、收集结构化结果、生成 JSON 报告。
android·python·pip
染指11103 小时前
151.Agent-LangGraph-Send发送(Map-Reduce模式)
人工智能·python·langchain·状态模式·agents
OKkankan3 小时前
python 进阶(三):面向对象进阶——从“会写 class”到设计可维护的后端对象
开发语言·数据结构·python
用户0332126663673 小时前
Python 办公自动化:用 Python 快速生成精美 PPT 演示文稿
python