P1017 进制转换
文章目录
题目信息
| 字段 | 内容 |
|---|---|
| 题号 | P1017 |
| 难度 | 红题(入门) |
| 知识点 | 数学、进制转换、递归 |
题目描述
将任意整数 n 转换成 r 进制数,并输出转换结果。
输入格式:两个整数 n 和 r,其中 -32768 ≤ n ≤ 32767,2 ≤ |r| ≤ 16。
输出格式:输出 n=r 进制的表示。
解题思路
核心思想
进制转换的核心是不断取余、除以基数。关键点在于负数的处理:
当 n 为负数时,直接取余会得到负的余数。例如 -1 mod -2 = -1,但我们需要的是正余数。
处理方法:
int remainder = value % base;
if (remainder < 0) {
remainder -= base; // 调整余数为正
value += base; // 调整被除数
}
这样保证了余数 remainder 在 [0, |base|-1] 范围内,最后使用递归先输出高位,再输出当前位。
算法流程
- 如果 value = 0,直接返回
- 计算余数 remainder = value mod base
- 如果 remainder < 0,调整 remainder 和 value
- 将 remainder 转换为对应字符(10→A, 11→B…)
- 递归处理 value/base,最后输出当前位
完整代码
C++
#include <cstdio>
#include <cstdlib>
#include <iostream>
#include <string>
// 将整数转换为指定进制的字符串表示
void convert_to_base(int value, int base, std::string* result) {
if (value == 0) {
return;
}
int remainder = value % base;
if (remainder < 0) {
remainder -= base;
value += base;
}
convert_to_base(value / base, base, result);
if (remainder >= 10) {
*result += static_cast<char>('A' + remainder - 10);
} else {
*result += static_cast<char>('0' + remainder);
}
}
int main() {
std::ios::sync_with_stdio(false);
std::cin.tie(nullptr);
int value = 0;
int base = 0;
std::cin >> value >> base;
std::string result;
if (value == 0) {
result = "0";
} else {
convert_to_base(value, base, &result);
}
std::cout << value << "=" << result << "(base" << base << ")" << "\n";
return EXIT_SUCCESS;
}
关键代码讲解
负数处理
int remainder = value % base;
if (remainder < 0) {
remainder -= base;
value += base;
}
这一步保证了余数永远为非负数。以 -1 ÷ -2 为例:
- -1 mod -2 = -1
- 调整后:remainder = -1 - (-2) = 1,value = -1 + (-2) = -3
- -3 ÷ -2 = 1 … 1
字符转换
if (remainder >= 10) {
*result += static_cast<char>('A' + remainder - 10);
} else {
*result += static_cast<char>('0' + remainder);
}
- 数字 0-9 直接加
'0'的 ASCII 值 - 字母 A-F 通过
'A' + (remainder - 10)得到
递归输出顺序
convert_to_base(value / base, base, result); // 先递归处理高位
*result += ...; // 后输出当前位
先递归到最深层,再逐层回溯输出,保证高位在前。
易错点
- 负数未正确处理:直接取余会导致结果出现负数位
- value=0 的边界情况:当 value=0 时,进制表示应为
0 - 字符与数字混淆:注意
'0'、'A'是字符,要正确转换
其他语言解法
Java
import java.io.*;
import java.util.*;
/**
* P1017 进制转换
* 将十进制整数转换为指定进制表示
*/
public class Main {
/** 将整数转换为指定进制的字符串并输出 */
private static void convertToBase(int value, int base) {
if (value == 0) {
return;
}
int remainder = value % base;
if (remainder < 0) {
remainder -= base;
value += base;
}
convertToBase(value / base, base);
if (remainder >= 10) {
System.out.print((char) ('A' + remainder - 10));
} else {
System.out.print((char) ('0' + remainder));
}
}
public static void main(String[] args) throws Exception {
BufferedReader br = new BufferedReader(new InputStreamReader(System.in));
StringTokenizer st = new StringTokenizer(br.readLine());
int value = Integer.parseInt(st.nextToken());
int base = Integer.parseInt(st.nextToken());
System.out.print(value + "=");
convertToBase(value, base);
System.out.println("(base" + base + ")");
}
}
Go
// Package main provides a solution for P1017 base conversion problem.
// 将十进制整数转换为指定进制表示,负数需要特殊处理。
package main
import (
"bufio"
"fmt"
"os"
)
// convertToBase 将整数转换为指定进制的字符串并输出
func convertToBase(value, base int) {
if value == 0 {
return
}
remainder := value % base
if remainder < 0 {
remainder -= base
value += base
}
convertToBase(value/base, base)
if remainder >= 10 {
fmt.Printf("%c", 'A'+remainder-10)
} else {
fmt.Printf("%c", '0'+remainder)
}
}
func main() {
in := bufio.NewReader(os.Stdin)
var value, base int
fmt.Fscan(in, &value, &base)
fmt.Print(value, "=")
convertToBase(value, base)
fmt.Printf("(base%d)\n", base)
}
JavaScript
'use strict';
/**
* 将整数转换为指定进制的字符串并输出
* @param {number} value - 待转换的整数
* @param {number} base - 目标进制
*/
function convertToBase(value, base) {
if (value === 0) {
return;
}
let remainder = value % base;
if (remainder < 0) {
remainder -= base;
value += base;
}
convertToBase(Math.trunc(value / base), base);
if (remainder >= 10) {
process.stdout.write(String.fromCharCode('A'.charCodeAt(0) + remainder - 10));
} else {
process.stdout.write(String.fromCharCode('0'.charCodeAt(0) + remainder));
}
}
const input = require('fs').readFileSync('/dev/stdin', 'utf8').trim().split(/\s+/);
const value = parseInt(input[0], 10);
const base = parseInt(input[1], 10);
process.stdout.write(`${value}=`);
convertToBase(value, base);
process.stdout.write(`(base${base})\n`);