把一个用 a 进制写的数转换成 b 进制输出。 数位的值为 10 及以上时用英文大写字母:A = 10,B = 11,…,Z = 35。 输入和输出都不带多余的前导 0(值为 0 时就是一个字符 0)。 第一行给出用空格隔开的 a 和 b,第二行给出用 a 进制写的数。
输入
2 ≤ a, b ≤ 36,这个数不小于 0 且按十进制不超过 10¹⁵,每一位是 0~9 或 A~Z,且值小于 a
输出
用 b 进制写的数(大写,无前导 0)
样例 1 · stdin
16 2
FF
stdout
11111111
样例 2 · stdin
10 36
1295
stdout
ZZ
main.py
错误列表00F8 ↓ · ⇧F8 ↑
输入(stdin)
运行时这些行会依次作为 input()/标准输入传入(运行中不会等待输入)。
$ 就绪
请在电脑上打开以编写和运行代码。在手机上可以查看题目和题解。
其他语言怎么写?查看各语言题解 · 8 种语言题解
读入时从高位开始 值 = 值 × a + 该位的值;写出时 值 % b 是最低位,所以每除一次就把字符加在前面,或者全部收集后再反转。 现成的工具各语言不同:Python int(s, a) 能读 2~36 进制,但没有写成 b 进制的函数(只有 bin、oct、hex)。 Java 的 Long.parseLong(s, a) 和 Long.toString(v, b) 都接受 2~36,JavaScript/TypeScript 也有 parseInt(s, a) 和 v.toString(b)——但 toString 输出的是小写(ff),需要 toUpperCase()。 C 用 strtoll(s, NULL, a)、C++ 用 std::stoll(s, nullptr, a) 读入,写出要自己做。 C# 的 Convert.ToInt64(s, base)、Convert.ToString(v, base)只接受 2、8、10、16 进制,其他会抛异常——所以两个方向都自己写。 Craykon 放一个 DIGITS = "0123…Z",用 DIGITS.查找位置(ch) 得到数位的值,用 DIGITS[v % b] 得到字符,商用 数学.商(v, b)。 四个陷阱:把所有数位都用 c - '0' 计算,'A' 会变成 17 而不是 10(C、C++、Java、C# 的字符减法)。 值为 0 时 while (v > 0) 一次也不执行,会输出空行(C、C++ 的解答用 do-while 避免了)。 把从低位得到的字符加在后面,顺序就反了。 另外 10¹⁵ 超过 int,要用 long/long long(JavaScript 和 Craykon 在 2^53 以内是精确的,所以没问题)。
Pythonmain.py · 14 行
DIGITS = "0123456789ABCDEFGHIJKLMNOPQRSTUVWXYZ"a, b = map(int, input().split())s = input().strip()value = int(s, a) # int()는 2~36진법 글자를 바로 읽는다(A = 10 … Z = 35)if value == 0: print("0")else: out = [] while value > 0: out.append(DIGITS[value % b]) # 낮은 자리부터 나온다 value //= b print("".join(reversed(out)))
import java.util.Scanner;public class Main { public static void main(String[] args) { Scanner sc = new Scanner(System.in); int a = sc.nextInt(), b = sc.nextInt(); String s = sc.next(); // Long.parseLong와 Long.toString은 2~36진법을 받는다. toString은 소문자를 내서 대문자로 바꾼다 long value = Long.parseLong(s, a); System.out.println(Long.toString(value, b).toUpperCase()); }}
C#Main.cs · 31 行
using System;using System.Text;class Program{ const string Digits = "0123456789ABCDEFGHIJKLMNOPQRSTUVWXYZ"; static void Main() { string[] ab = Console.ReadLine().Split(' ', StringSplitOptions.RemoveEmptyEntries); int a = int.Parse(ab[0]), b = int.Parse(ab[1]); string s = Console.ReadLine().Trim(); // Convert.ToInt64(s, base)는 2·8·10·16진법만 받아서 직접 바꾼다 long value = 0; foreach (char ch in s) value = value * a + Digits.IndexOf(ch); if (value == 0) { Console.WriteLine("0"); return; } var sb = new StringBuilder(); while (value > 0) { sb.Insert(0, Digits[(int)(value % b)]); // 낮은 자리부터 나오니 앞에 끼운다 value /= b; } Console.WriteLine(sb); }}
C++main.cpp · 20 行
#include <algorithm>#include <iostream>#include <string>int main() { const std::string digits = "0123456789ABCDEFGHIJKLMNOPQRSTUVWXYZ"; int a, b; std::string s; std::cin >> a >> b >> s; long long value = std::stoll(s, nullptr, a); // stoll은 2~36진법을 읽는다 std::string out; do { out += digits[value % b]; // 낮은 자리부터 나온다. do-while이라 0도 "0"이 된다 value /= b; } while (value > 0); std::reverse(out.begin(), out.end()); std::cout << out << '\n';}
Cmain.c · 21 行
#include <stdio.h>#include <stdlib.h>int main(void) { const char *digits = "0123456789ABCDEFGHIJKLMNOPQRSTUVWXYZ"; int a, b; char s[64]; scanf("%d %d %63s", &a, &b, s); long long value = strtoll(s, NULL, a); /* strtoll은 2~36진법을 읽는다 */ char out[64]; int len = 0; do { out[len++] = digits[value % b]; /* 낮은 자리부터 나온다. do-while이라 0도 "0"이 된다 */ value /= b; } while (value > 0); for (int i = len - 1; i >= 0; i--) putchar(out[i]); putchar('\n'); return 0;}
Craykonmain.cray · 28 行
DIGITS = "0123456789ABCDEFGHIJKLMNOPQRSTUVWXYZ";ab = 控制台.读数字();a = ab[0];b = ab[1];s = 控制台.读行().去空白();// a진법 글자를 앞에서부터 읽는다: 지금까지의 값 × a + 이 자리 값value = 0;遍历 (ch 在 s){ value = value * a + DIGITS.查找位置(ch);}如果 (value == 0){ 控制台.输出("0");}否则{ out = ""; 当 (value > 0) { out = DIGITS[value % b] + out; // 낮은 자리부터 나오니 앞에 붙인다 value = 数学.商(value, b); } 控制台.输出(out);}