1. 百练OJ平台与进制转换题目背景
百练OJ(OpenJudge Bailian)是北京大学ACM训练和相关程序课程在线考试系统,为编程学习者提供大量算法练习题和在线评测功能。这个平台收录了2000多道题目,涵盖从基础语法到高级算法的各个层面,是C++学习者提升编程能力的优质资源。
在百练OJ的题目列表中,"确定进制"是一道考察进制转换和基础算法思维的经典题目。这类题目通常给出某些数字在不同进制下的表示关系,要求编程确定具体的进制数值。解决这类问题需要掌握:
- 不同进制数的表示原理
- 进制之间的转换方法
- 边界条件的处理技巧
- 算法效率的优化思路
2. 问题分析与数学建模
2.1 题目理解与抽象化
假设题目描述为:给定三个数字p、q、r,以及等式"p * q = r"在某个未知进制下成立。要求编写程序找出这个进制的最小可能值(通常进制数大于数字中的最大数码)。
例如:
输入:11 11 121
输出:3
解释:在3进制下,11₃ * 11₃ = 121₃(即十进制4 * 4 = 16)
2.2 数学基础与进制转换
任何进制数转换为十进制都遵循多项式展开原理。对于一个k进制数aₙaₙ₋₁...a₀,其十进制值为:
decimal_value = aₙ × kⁿ + aₙ₋₁ × kⁿ⁻¹ + ... + a₀ × k⁰
实现这一转换的C++函数示例:
cpp复制int toDecimal(const string& num, int base) {
int decimal = 0;
for (char c : num) {
int digit = isdigit(c) ? c - '0' : c - 'A' + 10;
decimal = decimal * base + digit;
}
return decimal;
}
2.3 问题求解算法设计
基本解决思路:
- 确定最小可能进制的下限(数字中最大数码+1)
- 在合理范围内遍历可能的进制
- 对每个进制,将三个数转换为十进制验证等式
- 返回第一个满足条件的进制
需要考虑的特殊情况:
- 数字中可能包含字母(如A表示10)
- 进制上限的合理设置(避免无限循环)
- 前导零的处理
- 单个数字为0的情况
3. C++实现详解
3.1 基础版本实现
cpp复制#include <iostream>
#include <string>
#include <algorithm>
#include <cctype>
using namespace std;
int getMaxDigit(const string& s) {
int max_digit = 0;
for (char c : s) {
int digit = isdigit(c) ? c - '0' : toupper(c) - 'A' + 10;
max_digit = max(max_digit, digit);
}
return max_digit;
}
int toDecimal(const string& s, int base) {
int num = 0;
for (char c : s) {
int digit = isdigi
