1 条题解
-
1
问题分析
十进制转十六进制的核心是除16取余法:
- 将十进制数反复除以16,记录每次的余数;
- 余数范围为 0~15,其中 10~15 对应大写字母 A~F;
- 最后将余数倒序排列,得到十六进制数。
关键要点:
- 处理余数到字符的映射(10→A、11→B…15→F);
- 倒序输出余数序列(因为先得到的是低位,后得到的是高位);
- 输入范围 1≤n≤10⁹,需用整数类型(int/long long)处理,无溢出风险。
完整C++代码实现
#include <iostream> #include <string> #include <algorithm> // 用于reverse函数 using namespace std; int main() { long long n; // 用long long兼容更大范围(10^9在int范围内,但long long更安全) cin >> n; string hex_str; // 存储十六进制字符串 // 十六进制字符映射表:索引0~15对应0~F char hex_chars[] = "0123456789ABCDEF"; // 除16取余核心逻辑 while (n > 0) { int remainder = n % 16; // 取余数(0~15) hex_str += hex_chars[remainder]; // 转换为对应字符并追加到字符串 n = n / 16; // 整除16,继续处理高位 } // 反转字符串(因为余数是从低位到高位存储的) reverse(hex_str.begin(), hex_str.end()); // 输出结果 cout << hex_str << endl; return 0; }代码详细解释
1. 数据类型与输入
long long n; cin >> n;- 用
long long而非int:虽然 10⁹ 小于 int 的最大值(约2×10⁹),但long long能兼容更大的输入范围,避免潜在溢出; - 输入十进制数
n,满足 1≤n≤10⁹。
2. 余数映射与字符串拼接
char hex_chars[] = "0123456789ABCDEF"; while (n > 0) { int remainder = n % 16; hex_str += hex_chars[remainder]; n = n / 16; }hex_chars是预定义的映射表,索引直接对应余数,取值即可得到十六进制字符(如hex_chars[15] = 'F');- 循环逻辑:
n % 16取当前最低位的余数;- 将余数对应的字符追加到字符串;
n = n / 16去掉最低位,处理更高位;- 直到
n=0时停止循环。
3. 字符串反转与输出
reverse(hex_str.begin(), hex_str.end()); cout << hex_str << endl;- 由于余数是“低位→高位”存储的(如31的余数是15、1,拼接后是"F1"),需反转得到正确的“高位→低位”顺序("1F");
reverse函数来自<algorithm>头文件,直接反转字符串,简洁高效。
测试用例验证(样例1)
输入:
31执行过程:- 第一次循环:
31 % 16 = 15→ 字符F,hex_str = "F";31 / 16 = 1; - 第二次循环:
1 % 16 = 1→ 字符1,hex_str = "F1";1 / 16 = 0; - 循环结束,反转字符串 →
"1F"; - 输出
1F(与样例一致)。
边界情况测试
- n=16:余数依次为0、1 → 拼接"01" → 反转"10" → 输出
10; - n=15:余数15 → 拼接"F" → 反转后仍为"F" → 输出
F; - n=1000:1000 ÷16=62 余8 → 62÷16=3 余14 → 3÷16=0 余3 → 余数序列8、14、3 → 拼接"8E3" → 反转"3E8" → 输出
3E8。
总结
- 核心算法:除16取余法,通过余数映射表转换字符,反转字符串得到最终结果;
- 关键细节:
- 余数映射表直接索引取值,避免大量if-else判断;
- 必须反转字符串(余数存储顺序与最终结果相反);
- 用字符串存储结果,无需处理位数问题,适配任意长度的十六进制数;
- 效率分析:循环次数为 log₁₆(n)(最多9次,因为10⁹ < 16⁸),效率极高,完全满足时间限制。
- 1
信息
- ID
- 298
- 时间
- 1000ms
- 内存
- 512MiB
- 难度
- 3
- 标签
- 递交数
- 39
- 已通过
- 10
- 上传者