洛谷B3869题:位权法实现K进制转十进制

一、题目解读
洛谷B3869题目要求将输入的K进制数(2≤K≤16)转换为对应的十进制数值。用户需处理多组数据,每组包含进制K和K进制字符串,输出转换结果。题目考察进制转换的基本原理与算法实现,需确保对字符到数值的映射及权重计算的准确性。
二、解题思路
核心思路为“位权法”,即通过逐位解析K进制数的字符,将其映射为数值(0-15),并结合当前位的权重(k^(length-1-i))累加求和。关键在于设计字符转换函数(charToValue)与权重计算逻辑,避免复杂幂运算,通过循环迭代实现高效转换。
三、解题步骤
1. 输入处理:循环读取N组数据,每组解析K与num字符串。
2. 字符转换:通过charToValue函数将字符(‘0’-‘9’或‘A’-‘F’)转换为对应数值(0-15),非法字符返回-1(但题目保证不会出现)。
3. 权重计算:从右到左遍历num,每位权重为k^(length-1-i),通过result *= k + value迭代累加,避免递归或指数计算。
4. 输出结果:每组转换后的十进制数值单独输出。
四、代码与注释
#include <iostream>
#include <string>
#include <cmath>
using namespace std;
// 将字符转换为对应的数值(0-15)
int charToValue(char c) {
if (c >= '0' && c <= '9') return c - '0'; // 数字字符直接映射
if (c >= 'A' && c <= 'F') return 10 + (c - 'A'); // 字母字符映射为10-15
return -1; // 非法字符(题目保证不会出现)
}
// 将K进制字符串转换为十进制数
long long kToDecimal(const string& num, int k) {
long long result = 0;
int length = num.length();
for (int i = 0; i < length; ++i) {
int value = charToValue(num[i]); // 获取当前字符数值
// 计算当前位的权重:k^(length-1-i)
result = result * k + value; // 更高效的计算方式(避免幂运算)
}
return result;
}
int main() {
ios::sync_with_stdio(false); // 加快输入/输出
cin.tie(nullptr);
int N;
cin >> N;
for (int i = 0; i < N; ++i) {
int K;
string num;
cin >> K >> num;
cout << kToDecimal(num, K) << "\n"; // 输出转换结果
}
return 0;
}五、总结
本解法通过位权法实现了K进制到十进制的线性时间转换,关键在于字符映射与权重迭代计算的优化。代码简洁高效,避免了复杂数学库依赖,适用于竞赛及实际开发中的进制转换场景。理解位权法的逻辑对掌握进制转换算法至关重要,建议结合实例调试以加深理解。
原创内容 转载请注明出处





