P4039与P4040 C++进制转换经典解法(无vector/oct)
好的,我们来一次性解决这两道题。我将为你提供符合题目要求(**不使用 `vector`,不使用 `oct`**)的C++解法,并附上详细解释。 --- ## 🎯 题目一:P4039 进制转换(十进制转任意进制,M≤10) ### 问题分析 核心算法依然是“**除基取余法**”。我们用一个静态数组来存储每一位的余数,最后逆序输出。 ### 💻 代码实现 ```cpp #include <iostream> using namespace std; int main() { int X, M; cin >> X >> M; // 边界情况:如果X是0,直接输出0(任何进制下,0都是0) if (X == 0) { cout << 0 << endl; return 0; } // 定义一个足够大的数组 // 十进制数X最大为10^9,二进制需要的位数最多(约30位),这里取32位足够 int result[32]; int index = 0; // 除基取余法(基数是M) while (X > 0) { result[index] = X % M; // 存储余数 X /= M; // 更新商 index++; } // 逆序输出 for (int i = index - 1; i >= 0; i--) { cout << result[i]; } cout << endl; return 0; } ``` ### 📖 代码详解 1. **输入读取**:`X` 是十进制数,`M` 是目标进制(题目保证 `M ≤ 10`)。 2. **数组 `result[32]`**:静态数组,用来存储每一位的余数。32 的大小对于题目范围绝对安全。 3. **循环过程**: - `X % M`:取出当前最低位(余数)。 - `X / M`:去掉最低位,更新商。 - 循环直到 `X` 变成 0。 4. **逆序输出**:从 `index-1` 到 `0`,依次输出数组中的元素,即得到正确的进制表示。 ### 📊 示例:输入 `11 2` | X | X % 2 | 存入数组 | index | X /= 2 | |----|-------|----------|-------|--------| | 11 | 1 | [0] | 1 | 5 | | 5 | 1 | [1] | 2 | 2 | | 2 | 0 | [2] | 3 | 1 | | 1 | 1 | [3] | 4 | 0 | 循环结束,`index = 4`。逆序输出 `[3][2][1][0]` → `1 0 1 1` → `1011`。正确! --- ## 🎯 题目二:P4040 小核桃的疑惑 ### 问题分析 这个题目是进制转换的直接应用: 1. 输入一个十进制数 **A** 和一个二进制数 **B**(注意:**B 以字符串形式输入**)。 2. 先将二进制数 **B** 转换为十进制数。 3. 计算 **A - B**,输出结果(十进制)。 ### 💻 代码实现 ```cpp #include <iostream> #include <string> using namespace std; int main() { int A; string B_str; // 二进制数以字符串形式读取 cin >> A >> B_str; // 1. 将二进制字符串 B_str 转换为十进制整数 int B = 0; for (int i = 0; i < B_str.length(); i++) { B = B * 2 + (B_str[i] - '0'); // 逐位转换 } // 2. 计算结果 int result = A - B; // 3. 输出 cout << result << endl; return 0; } ``` ### 📖 代码详解 1. **输入处理**: - `A` 是十进制整数,直接 `cin >> A`。 - `B` 是二进制数,但题目以字符串形式给出(如 `"1101"`),所以用 `string` 类型读取。 2. **二进制转十进制**:经典的“乘2累加法”: - 从左到右遍历字符串的每一位。 - 每次将当前结果乘以 2,再加上当前位的数值(`'0'` 的 ASCII 是 48,减去 `'0'` 得到整数 0 或 1)。 - 例如 `"1101"`:`((1*2+1)*2+0)*2+1 = 13`。 3. **计算差值**:`result = A - B`。 4. **输出结果**:直接输出十进制结果 `result`。 ### 📊 示例:输入 `15` 和 `"1101"` - `A = 15` - 二进制 `"1101"` 转十进制:`((1*2+1)*2+0)*2+1 = 13` - 结果:`15 - 13 = 2` - 输出:`2`。正确! --- ## ✅ 开发建议与最佳实践 1. **边界情况处理**: - 对于 P4039,不要忘记处理 `X = 0` 的情况。 - 对于 P4040,注意二进制字符串 `B` 可能以 `"0"` 开头,但题目没有明确说明,我们的算法依然能正确工作。 2. **数组大小选择**: - 对于 `int` 范围的数,二进制最多需要 31 位,八进制 11 位。**数组大小为 32 是绝对安全的**。 3. **使用 `string` 处理二进制输入**: - 二进制数可能很长(最长 10 位),用整型直接读入可能丢失前导零,所以用字符串最安全。 - 注意:题目中二进制数以十进制形式输入(如 `1101`),但用 `string` 读取可以避免解析问题。 4. **代码可读性**:对于核心算法(进制转换、二进制转十进制),建议写成函数,便于复用。 ## 🚫 常见陷阱规避 - **P4039 忘记逆序**:一定记得从数组末尾向前输出。 - **P4040 误用整型读入二进制数**:如果直接 `cin >> int B`,输入 `1101` 会被当作一千一百零一,而不是二进制数。必须用字符串读入。 - **二进制转十进制算法**:注意遍历方向是从左到右(高位到低位),不要搞反。 ## 🔧 扩展思考 - **如果 M > 10 怎么办?** 需要将余数 10~15 映射为字符 `A~F`。可以用一个字符数组或者 `if-else` 处理。 - **如果 B 是负数怎么办?** P4040 题目未提及,通常二进制数表示无符号正整数。如果考虑有符号,需要额外处理补码表示。 - **如果 A < B 怎么办?** 题目未说明,但一般结果可能为负。直接相减输出即可(C++ 支持负数)。 --- ######[AI写代码神器 | 1648点数解答 | 2026-07-22 09:40:07]
- P3350发射站:从稀疏表优化到单调栈满分解答(DeepSeek | 1869点数解答 | 2026-07-05 10:55:10)20
- 解决 C++ 代码 “vector 未声明” 等错误:实现字符串单词反转功能(字节豆包 | 489点数解答 | 2025-11-12 14:49:29)110
- 优化代码解决超时问题:计算数组 f(l, r) 最小和(字节豆包 | 821点数解答 | 2026-05-10 16:15:59)30
- 优化代码解决超时问题:计算所有 f(l, r) 的和(字节豆包 | 767点数解答 | 2026-05-10 16:17:49)56
- 修复代码:让含随机元素的 Win32 游戏界面代码正常运行(GPT | 2686点数解答 | 2024-10-31 15:01:39)404
- C++ 代码:巧妙计算 n×n 矩阵行、列、对角线平行直线元素和最大值(字节豆包 | 1151点数解答 | 2025-11-26 20:07:49)65
- C++ 简单方块世界玩家移动代码:分析、优化与注意事项揭秘(字节豆包 | 881点数解答 | 2025-12-20 19:47:37)83
- C++游戏代码中枚举类型定义报错原因及解决方案(字节豆包 | 371点数解答 | 2026-02-27 20:29:12)65
- C++实现不使用vector交换矩阵指定两列(字节豆包 | 556点数解答 | 2026-04-25 20:21:57)45
- C++代码:模拟粒子炮与集束粒子炮攻击护盾效果及优化(字节豆包 | 1261点数解答 | 2026-05-01 17:30:09)52
- 优化代码避免TLE:计算所有 f(l, r) 的和(字节豆包 | 765点数解答 | 2026-05-10 16:19:03)37
- 解决代码WA问题:修改整数溢出问题后的计算代码(字节豆包 | 749点数解答 | 2026-05-10 16:20:03)73