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] 范围内,最后使用递归先输出高位,再输出当前位。

算法流程

  1. 如果 value = 0,直接返回
  2. 计算余数 remainder = value mod base
  3. 如果 remainder < 0,调整 remainder 和 value
  4. 将 remainder 转换为对应字符(10→A, 11→B…)
  5. 递归处理 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 += ...;  // 后输出当前位

先递归到最深层,再逐层回溯输出,保证高位在前。

易错点

  1. 负数未正确处理:直接取余会导致结果出现负数位
  2. value=0 的边界情况:当 value=0 时,进制表示应为 0
  3. 字符与数字混淆:注意 '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`);