PAT 1022. D进制的A+B

1022. D进制的A+B (20)

时间限制
100 ms
内存限制
65536 kB
代码长度限制
8000 B
判题程序
Standard
作者
CHEN, Yue

输入两个非负10进制整数A和B(<=230-1),输出A+B的D (1 < D <= 10)进制数。

输入格式:

输入在一行中依次给出3个整数A、B和D。

输出格式:

输出A+B的D进制数。

输入样例:
123 456 8
输出样例:

1103


#include <stdio.h>


int main() {
int num[40] = {
0
};
int A, B, D, n, i;
scanf("%d%d%d", &A, &B, &D);
n = A + B;
if(n == 0) {
printf("0");
} else {
i = 0;
while(n != 0) {
num[i ++] = n % D;
n = n / D;
}
for(i = 39; i >= 0 && num[i] == 0; i --);
for(; i >= 0; i --) {
printf("%d", num[i]);
}
}
return 0;
}                         
                          

地球人习惯使用十进制数,并且默认一个数字的每一位都是十进制的。而在 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 数之和。(用C语言编写程序)
最新发布
03-17
### 实现基于自定义进制表的PAT数加法 为了实现基于自定义进制表的两个PAT数的加法运算,可以通过以下方式设计程序逻辑: #### 程序功能描述 1. **读取输入**:接收用户输入的进制表以及两个待相加的PAT数。 2. **逐位相加**:从最低位开始逐位相加,并依据进制表中的规则处理进位。 3. **输出结果**:最终输出两数之和。 以下是完整的C语言代码实现[^1]: ```c #include <stdio.h> #include <string.h> #define MAX_LEN 20 // 假设最多支持20位长度 // 函数声明 void reverse(char *str); char add_with_carry(int digit_a, int digit_b, int base[], int pos, int *carry); int main() { char pat1[MAX_LEN + 1], pat2[MAX_LEN + 1]; int base_table[MAX_LEN]; // 存储进制表 int length; // 输入部分 printf("Enter the number of digits (<= %d): ", MAX_LEN); scanf("%d", &length); if (length > MAX_LEN || length <= 0) { printf("Invalid input.\n"); return 1; } printf("Enter the first PAT number (from lowest to highest bit): "); scanf("%s", pat1); if (strlen(pat1) != length) { printf("Length mismatch for PAT1.\n"); return 1; } printf("Enter the second PAT number (from lowest to highest bit): "); scanf("%s", pat2); if (strlen(pat2) != length) { printf("Length mismatch for PAT2.\n"); return 1; } printf("Enter the base table (space-separated values from lowest to highest bit): "); for (int i = 0; i < length; ++i) { scanf("%d", &base_table[i]); if (base_table[i] < 2 && base_table[i] != 0) { // 验证进制合法性 printf("Base must be >= 2 or equal to 0 (for decimal).\n"); return 1; } } // 处理部分 int carry = 0; // 初始化进位为0 char result[MAX_LEN + 1]; for (int i = 0; i < length; ++i) { int a = pat1[i] - '0'; // 转换字符为数字 int b = pat2[i] - '0'; int current_base = base_table[i] ? base_table[i] : 10; // 如果进制为0,则视为10进制 result[i] = add_with_carry(a, b, base_table, i, &carry); // 计算当前位的结果并更新进位 } if (carry > 0) { // 若最高位仍有进位,则需扩展结果 printf("Overflow occurred due to final carry.\n"); } else { result[length] = '\0'; // 结束字符串 reverse(result); // 反转结果以便按高位到低位显示 printf("The sum is: %s\n", result); } return 0; } // 辅助函数:反转字符串 void reverse(char *str) { int len = strlen(str); for (int i = 0; i < len / 2; ++i) { char temp = str[i]; str[i] = str[len - i - 1]; str[len - i - 1] = temp; } } // 辅助函数:计算单个位置上的加法规则 char add_with_carry(int digit_a, int digit_b, int base[], int pos, int *carry) { int total = digit_a + digit_b + (*carry); int current_base = base[pos] ? base[pos] : 10; // 判断当前位置的实际进制 *carry = total / current_base; // 更新进位 return (total % current_base) + '0'; // 返回该位的结果字符 } ``` #### 关键点解析 1. **进制表的作用**:通过`base_table[]`数组存储每位对应的进制值。当某位的进制为0时,默认其为十进制[^4]。 2. **逐位相加与进位处理**:对于每一位,先将其转换为数值形式(即减去字符‘0’),再利用模运算 `%` 和除法 `/` 来分别获取余数(本位结果)和商(进位值)。此过程遵循指定的进制规则。 3. **溢出检测**:如果在最高位仍存在未处理的进位,则提示发生溢出情况。 #### 示例运行 假设输入如下: - 数字长度:4 - 第一个PAT数:`3210` - 第二个PAT数:`4567` - 进制表:`7 2 5 10` 程序将依次执行逐位加法操作,并考虑各位置的不同进制约束条件。 --- ###
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值