1074 宇宙无敌加法器 ——c++实现

题目

1074 宇宙无敌加法器 (20 分)

地球人习惯使用十进制数,并且默认一个数字的每一位都是十进制的。而在 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

算法

数据结构:用C语言编程由于无法定义字符串类型,一般定义成字符数组来存储。字符数组存储时会默认在最后加上一个’\0‘,但是统计字符数组长度的时候,不统计末尾的’\0‘。

无论是C/C++中,获得字符数组的长度可以使用strlen函数,如计算字符数组a的长度的语句是i=strlen(a)。
头文件:#include
功能:计算给定字符串的(unsigned int型)长度,不包括'\0'在内;
参数说明:要计算长度的字符串数组的首地址
返回值说明:要计算字符串的长度,不包括'\0'。

显然sBase的长度比sA,sB大,因此在需要将sA,sB,sBase的各位数字取出来的时候就要注意,sA,sB不存在高位就要补零,同时sBase的0相当于10要注意,因此有下面的代码:

for(int i = 0; i < nBase; i++) { 
                /* Transform corresponding digit to integers */ 
		a = nA <= i ? 0 : sA[nA - i - 1] - '0'; 
		b = nB <= i ? 0 : sB[nB - i - 1] - '0'; 
		base = sBase[nBase - i - 1] - '0'; 
		base = base == 0 ? 10 : base; 

后面就需要计算sA,sB对应位的数字之和,同时将计算结果存储在sSum,要注意可能会有进位。这里运算的都是整数,因此后面需要将其转换为字符。

/* Calculate ith digit A + B, temperately store integers here */ 
		sSum[nS - i - 1] += a + b; 
		sSum[nS - i - 2] += sSum[nS - i - 1] / base; 
		sSum[nS - i - 1] = sSum[nS - i - 1] % base; 

将计算的sSum中的数字字符读出来可以采用将数字与‘0’相加的形式,就可以得到对应的数字字符(ASCII码)。在输出时,找到第一个非零位开始输出,注意puts()函数时输出字符串的,只要指明这个字符串的首地址即可。

在输出的时候,puts()函数会自动将字符串结尾的‘\0'转化成回车换行。输出之后return 0,就会退出主函数main()。如果一直没有找到非零位,则说明sA+sB=0,因此只需要输出0即可。如果不写这个条件,就会遗漏和为0的情况。

代码

#include  
#include  
int main() { 
	int nBase, nA, nB, nS = 21, base, a, b; 
	char sBase[21] = {0}, sA[21] = {0}, sB[21] = {0}, sSum[22] = {0}; 
	/* Read base table, number A and B into strings */ 
	scanf("%s %s %s", sBase, sA, sB); 
	nBase = strlen(sBase); 
	nA = strlen(sA); 
	nB = strlen(sB); 
	for(int i = 0; i < nBase; i++) { 
                /* Transform corresponding digit to integers */ 
		a = nA <= i ? 0 : sA[nA - i - 1] - '0'; 
		b = nB <= i ? 0 : sB[nB - i - 1] - '0'; 
		base = sBase[nBase - i - 1] - '0'; 
		base = base == 0 ? 10 : base; 
		/* Calculate ith digit A + B, temperately store integers here */ 
		sSum[nS - i - 1] += a + b; 
		sSum[nS - i - 2] += sSum[nS - i - 1] / base; 
		sSum[nS - i - 1] = sSum[nS - i - 1] % base; 
	} 
        /* Change to char type */ 
	for(int i = 0; i < 21; i++) sSum[i] += '0'; 
        /* find the first non-zero bit */ 
	for(int first = 0; first < 21; first++) 
		if(sSum[first] != 0 && sSum[first] != '0') { 
			puts(sSum + first); 
                        return 0; 
		} 
        /* If A + B = 0, then all bits are zero */ 
	printf("0"); 
	return 0; 
}

代码参考:PAT Basic 1074. 宇宙无敌加法器(20)(C语言实现)

注意:

1如果往string变量中输入一个数字输出也是一个数字

2如果往string变量中输入一个数字,但需要进行计算的时候需要-'0'

3通过两个数字相加得到的第三个数字存入string中的时候,需要+'0'

你可能感兴趣的:(1074 宇宙无敌加法器 ——c++实现)