A + B Problem II
A + B Problem II
Problem Description(问题描述)
I have a very simple problem for you. Given two integers A and B, your job is to calculate the Sum of A + B.
Input(输入)
The first line of the input contains an integer T(1<=T<=20) which means the number of test cases. Then T lines follow, each line consists of two positive integers, A and B. Notice that the integers are very large, that means you should not process them by using 32-bit integer. You may assume the length of each integer will not exceed 1000.
Output(输出)
For each test case, you should output two lines. The first line is “Case #:”, # means the number of the test case. The second line is the an equation “A + B = Sum”, Sum means the result of A + B. Note there are some spaces int the equation. Output a blank line between two test cases.
Sample Input(样例输入)
1
100
Sample Output(样例输出)
Case 1:
1 + 2 = 3
Case 2:
112233445566778899 + 998877665544332211 = 1111111111111111110
题目大意
这个是1000的升级版本。
先给你一个n,表示这一次测试用例的数目。
然后,有n行,每行两个数,求和。
第一,要注意数据范围,可能很大,每个整数的长度不超过1000。
第二,这个就是为了学会输出“case” 这些东西,在复杂的题目,有很多都会有一些格式的输出。
要注意空格的输出。
每个答案输出之后都要有一个空行。
分析
这是杭电Online Exercise的第三题。
但是在前面十几题通过率都在百分之二十甚至三十以上的简单题目中,他的通过率只有百分之十九,看来有点东西。
主要就在于这两个数字是非常长的,如果我们用c++提供的数据类型,部分测试数据肯定是不能过的。
那怎么办?
肯定要分解这种大数相加。
最普遍的思路,就是将数字当做字符串进行输入,然后进行相加。
相加的过程就如同小学学的手算一样,一位一位的进行,如果进位则前一位+1。
但如果我们就直接输入来加,又有这么几种情况。
1、两个数字长度不一样,如何“对齐”?例如123456789+1,怎么样把1加到9?
2、如果最高位再次进1,这个进1加到哪里?例如999+1,最后等于1000,可是输入的时候字符串“999”就是三位,最后这个进1如何处理呢?
所以,最好的方法应该是将作为字符串读入的两个数字,先逆序。
例如1234567+9876,逆序成7654321 和 6789,直接就可以从两个字符串的头开始对齐相加。
长度不一样的话,可以通过补0的方式来实现。
但如果补0,就一定要考虑 0+0 的情况了哦!!!!!!
关于字符串倒序,看到一位博主讲的很细致。贴上链接。https://blog.csdn.net/m0_37717595/article/details/80539957
程序有一些步骤的解释,都写在注释里了,如果有意见可以指出,一起学习!
#define _CRT_SECURE_NO_WARNINGS
#include <iostream>
#include <stdlib.h>
#include <string.h>
using namespace std;
void overturn(char* one,char* another);//翻转输入的字符数组
int main()
{
int n;
cin >> n;
char a[1001];
char b[1001];//a和b存储输入的两个数字
char over_a[1010];
char over_b[1010];//over_a 和 over_b 存储倒序之后的两个数字
//为什么a倒序还要存到另一个over_a里面,直接存a里面不行吗?
//因为输入格式的要求,还要将原数输入。
for (int i = 1; i <= n; i++)
{
cin >> a;
cin >> b;
overturn(a,over_a);
overturn(b,over_b);
for (int j=0; j <=1000 ; j++)
{
over_a[j] = over_a[j] + (over_b[j] - '0');
if (over_a[j] > '9')
{
over_a[j] = (over_a[j] - '9' - 1) + '0';
over_a[j + 1] = over_a[j + 1]++;
}
}
//字符上的加减,其实和整数差不多。
//例如字符‘0’加上3,就是‘3’。
//其实这里也可以再建一个整形数组来存结果,差不多。
int k;
for ( k = 1000; k > 0; k--)//注意这里k大于0
{
if (over_a[k] != '0')
break;
}//用于排除我们方便计算而补上的与数值大小无关的0
cout << "Case " << i << ":" << endl;
cout << a <<" + "<<b <<" = ";
for (k; k >= 0; k--)//注意这里k等于0
{
cout << over_a[k];
}
//为什么要前一个循环k不取0,而后一个循环取0呢?
//因为这是为了考虑0+0的情况,如果我们在前面取到0,如果输入的数字就是0,岂不是也给排除了?
//所以前一个k不取0,即便输入的就是0,也能正常输出。
cout << endl;
if (i != n) //最后一个输入结束时,不再输出空行。
cout << endl;
}
return 0;
}
void overturn(char* one, char* another)
{
char* p1 = NULL;
char* p2 = NULL;
if (one == NULL)
return;
strcpy(another, one);
int len = strlen(another);
p1 = another;
p2 = another + (len - 1);
while (p2 > p1)
{
char temp_c = *p1;
*p1 = *p2;
*p2 = temp_c;
++p1;
--p2;
}
p1 = another+len ;//指向倒序之后的字符串的末尾,即'\0'
for (int i = 0; (i + len) < 1009; i++)
{
*p1 = '0';//补0
p1++;
}
*p1 = '\0';
}
这样就可以通过了。
总结
相对于前两题,是一个比较大的提升,但也是很简单的题目,不要被吓到。
一定要处理好字符串的字符处理,不要再倒序的时候因为一些问题产生最后的字符数组越界。