PAT 乙级 1074.宇宙无敌加法器 C++/Java
地球人习惯使用十进制数,并且默认一个数字的每一位都是十进制的。而在 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
思路:
由于输入的进制位数N是在[0,20]间,整型和长整型放不下,并且为了方便按位求和,可以采用数组来存放。使用getchar()来获取每位输入,当输入不为'\n'时,就存放进整形数组中。再分别将三个数组逆序,不足N位的数字就在补0(实际上就是在两个数字的前面补0)。然后从两个数字的个位开始,遍历N次,两个数字按位相加并加上进位,除以该位的进制得到进位jw,余数则存放在结果数组res[]中,遍历完成后,将最后的进位也存放进res[]中。最后将res逆序,从第一个不为0的数开始输出。若两数求和的结果就是0,则要输出0(测试点5)。
C++实现:
1 #include <iostream> 2 #include <vector> 3 #include <algorithm> 4 using namespace std; 5 //1074:宇宙无敌加法器 6 int main() { 7 vector<int> change, num1, num2, res; 8 char a; 9 while ((a = getchar()) != '\n') { change.push_back(a - '0'); } 10 while ((a = getchar()) != '\n') { num1.push_back(a - '0'); } 11 while ((a = getchar()) != '\n') { num2.push_back(a - '0'); } 12 int N = change.size(); 13 reverse(change.begin(), change.end()); 14 reverse(num1.begin(), num1.end()); 15 reverse(num2.begin(), num2.end()); 16 while (N > num1.size()) { num1.push_back(0); } 17 while (N > num2.size()) { num2.push_back(0); } 18 int sum, ch, jw = 0; 19 for (int i = 0; i < N; i++) { 20 sum = num1[i] + num2[i] + jw; 21 ch = change[i]; 22 if (ch == 0) ch = 10; 23 res.push_back(sum % ch); 24 jw = sum / ch; 25 } 26 res.push_back(jw); 27 reverse(res.begin(), res.end()); 28 bool flag = false; 29 for (int i = 0; i < res.size(); i++) { 30 if (res[i] > 0 || flag) { 31 flag = true; 32 cout << res[i]; 33 } 34 } 35 if (!flag) cout << "0"; 36 return 0; 37 }
Java实现: