PAT 1074.宇宙无敌加法器

题目

地球人习惯使用十进制数,并且默认一个数字的每一位都是十进制的。而在PAT星人开挂的世界里,每个数字的每一位都是不同进制的,这种神奇的数字称为“PAT数”。每个PAT星人都必须熟记各位数字的进制表,例如“……0527”就表示最低位是7进制数、第2位是2进制数、第3位是5进制数、第4位是10进制数,等等。每一位的进制d或者是0(表示十进制)、或者是[2,9]区间内的整数。理论上这个进制表应该包含无穷多位数字,但从实际应用出发,PAT星人通常只需要记住前20位就够用了,以后各位默认为10进制。

在这样的数字系统中,即使是简单的加法运算也变得不简单。例如对应进制表“0527”,该如何计算“6203+415”呢?我们得首先计算最低位:3+5=8;因为最低位是7进制的,所以我们得到1和1个进位。第2位是:0+1+1(进位)=2;因为此位是2进制的,所以我们得到0和1个进位。第3位是:2+4+1(进位)=7;因为此位是5进制的,所以我们得到2和1个进位。第4位是:6+1(进位)=7;因为此位是10进制的,所以我们就得到7。最后我们得到:6203+415=7201。

输入格式:

输入首先在第一行给出一个N位的进制表(0 < N <=20),以回车结束。 随后两行,每行给出一个不超过N位的正的PAT数。

输出格式:

在一行中输出两个PAT数之和。

输入样例:

30527
06203
415

输出样例:

7201

我的解决方案

1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
66
67
68
69
70
71
72
73
74
75
76
77
78
79
80
81
82
83
84
85
86
87
88
89
90
91
92
93
94
95
96
97
98
99
100
101
#include <stdio.h>
#include <string.h>

#define SIZE 30

int ctoi(char c)
{ return c - '0'; }

char itoc(int i)
{ return i + '0'; }

//读取一行并丢弃换行
void getLine(char *s, int size)
{
fgets(s, size, stdin);
s[strlen(s) - 1] = '\0';
}

//在数字前补count个0
void addZero(char *s, size_t count)
{
char tmp[SIZE];

strcpy(tmp, s);
while (count--) {
*s++ = '0';
}
strcpy(s, tmp);
}

//反转字符串
void reverse(char *s)
{
char *p = s + strlen(s) - 1;

while (s < p) {
char tmp = *s;

*s = *p;
*p = tmp;
++s;
--p;
}
}

//打印num
void printNum(const char *num)
{
//忽略前导0
while (*num && *num == '0') {
++num;
}
if (!*num) {
putchar('0');
}
printf("%s", num);
}

int main(void)
{
char table[SIZE]; //进制表
char a[SIZE], b[SIZE], c[SIZE];
int size = 0;
int flag = 0;
int i, j, k;

getLine(table, SIZE);
getLine(a, SIZE);
getLine(b, SIZE);

i = strlen(a);
j = strlen(b);
k = strlen(table);

//短的数字前面补0
if (i < j) {
addZero(a, j - i);
i = j;
}
else {
addZero(b, i - j);
}

//从后往前逐项计算
while (--i >= 0 && --k >= 0) {
int base = table[k] == '0' ? 10 : ctoi(table[k]);

flag += ctoi(a[i]) + ctoi(b[i]);
c[size++] = itoc(flag % base);
flag /= base;
}
//进位
if (flag) {
c[size++] = itoc(flag);
}
c[size] = '\0';

reverse(c);
printNum(c);
printf("\n");
}
Author: sphc
Link: https://jkuvw.xyz/archives/61cae029/
Copyright Notice: All articles in this blog are licensed under CC BY-NC-SA 4.0 unless stating additionally.
微信打赏
支付宝打赏