PTA 7-22 BCD解密 题解
PTA 7-22 BCD解密 题解
题目:
BCD数是用一个字节来表达两位十进制的数,每四个比特表示一位。所以如果一个BCD数的十六进制是0x12,它表达的就是十进制的12。但是小明没学过BCD,把所有的BCD数都当作二进制数转换成十进制输出了。于是BCD的0x12被输出成了十进制的18了!
现在,你的程序要读入这个错误的十进制数,然后输出正确的十进制数。提示:你可以把18转换回0x12,然后再转换回12。
输入格式:
输入在一行中给出一个[0, 153]范围内的正整数,保证能转换回有效的BCD数,也就是说这个整数转换成十六进制时不会出现A-F的数字。
输出格式:
输出对应的十进制数。
输入样例:
18
输出样例:
12
解析
BCD数是什么
我们先学习一下什么是 \(\texttt{BCD}\) 数:
\(\texttt{BCD(Binary-Coded Decimal}\) 是一种编码方式,它将每个十进制数字转换为四位的二进制数。在 \(\texttt{BCD}\)编码中,每个十进制位(\(\texttt{digit}/\))都是独立编码的,而不是像普通的二进制那样表示整个数值。
在 \(\texttt{BCD}\) 编码中,每个十进制数字(从 \(0\) 到 \(9\))被表示为四位二进制数,范围从 \(0000\)(表示十进制的 \(0\))到 \(1001\)(表示十进制 \(9\))。以下是十进制数字与对应的 \(\texttt{BCD}\) 编码:
十进制 BCD编码(二进制) BCD编码(十六进制)
0 0000 0x0
1 0001 0x1
2 0010 0x2
3 0011 0x3
4 0100 0x4
5 0101 0x5
6 0110 0x6
7 0111 0x7
8 1000 0x8
9 1001 0x9
例如一个 \(\texttt{BCD}\) 编码的十六进制数 0x12,它是按照以下方式解释的:
第一部分(高四位):0x1,对应的二进制是0001,表示十进制的1。
第二部分(低四位):0x2,对应的二进制是0010,表示十进制的2。
妙手解题
于是我们发现,在题目给定的数字范围内,二进制前四位为一个编码,后四位为一个编码,由二进制解释为两个结果后组合成一个 \(\texttt{BCD}\) 数。
那么解题就非常简单了,我们可以理解为,小明只是改变了一个数字的“显示方式”,但是没有改变这个数本身,简单来说,小明将一串二进制数以二进制的算法操作成为了错误的十进制数,题目的正确方法是将这串二进制以 \(\texttt{BCD}\) 编码成一个 \(\texttt{BCD}\) 数,我们要做的是将还原出这串二进制编码,再将其变成十进制数。
为什么要讲这么多,因为以下方法堪称妙手:
我们把小明的错误结果除以 \(16\) 就是前四位二进制数(表示的数),剩余的就是后四位二进制数(表示的数),二者直接接起来就是正确的十进制数。
满分代码:
//javac
import java.util.Scanner;
public class Main {
public static void main(String[] args) {
Scanner scan = new Scanner(System.in);
int n = scan.nextInt();
if(n!=0) System.out.printf("%d%d", n/16, n%16);
else System.out.print("0");
scan.close();
}
}
//cpp
#include <iostream>
#include <cstdio>
int main() {
int n;
std::cin >> n;
if(n != 0) {
printf("%d%d", n/16, n%16);
} else {
std::cout << "0";
}
return 0;
}

浙公网安备 33010602011771号