先看例题
-
总时间限制: 1000ms 内存限制: 65536kB
-
描述:求两个不超过200位的非负整数的和。
-
输入:有两行,每行是一个不超过200位的非负整数,可能有多余的前导0。
-
输出:一行,即相加后的结果。结果里不能有多余的前导0,即如果结果是342,那么就不能输出为0342。
-
样例输入
22222222222222222222
33333333333333333333 -
样例输出
55555555555555555555
(1)思路
-
200位显然超过基本数据类型能表达的范围,无法直接做加法,可以模拟竖式加法解决
-
使用字符数组或字符串存储加数,转换为整形,根据加法进位规则计算,最后再转化为字符型输出
-
AC代码如下(写的有点麻烦了,仅供参考)
#include<stdio.h> int X1[210]={0};//若在reverse中定义,在返回主函数时就释放空间了,返回乱数 int X2[210]={0};//开大一点,避免200位极限情况出错 //把字符数组转换为int型,逆序,并存在数组最后 int *reverse(char *a,int n,int *X) { int *p=X; for(int i=0;i<n;i++) { X[209-i]=a[i]-'0'; } return p; } int main() { char A[210]={'a'}; char B[210]={'a'}; int *pa,*pb; int C[210]={0},flag=1; //读取数据,使用getchar() int i=209; A[i]=getchar(); while(A[i]!='\n') A[--i]=getchar(); pa=reverse(&A[i+1],209-i,X1); i=209; B[i]=getchar(); while(B[i]!='\n') B[--i]=getchar(); pb=reverse(&B[i+1],209-i,X2); //对应位相加,注意进位 for(int i=209;i>=0;i--) { C[i]+=(pa[i]+pb[i]); if(C[i]>=10) C[i-1]+=1,C[i]-=10; } //换为字符型输出 for(int i=0;i<210;i++) { char c='0'+C[i]; //高位的0不输出 if(flag) { if(C[i]!=0) flag=0,printf("%c",c); } else printf("%c",c); } //全部都是0,计算结果为0 if(flag) printf("%d",0); return 0; }
tips:
- 注意计算结果为0时的情况,不要忘记
- 数组开大一点,避免极限数据(200位长)时出错
(2)补充
-
过了很久之后又做到大整数加法了,用string来做一波
#include <iostream> #include <algorithm> #include <string> #include <vector> #include <cmath> using namespace std; //大数加法 string add(string a,string b) { string res; //短的数补0,方便计算 int t = a.length()-b.length(); if(t>0) b.insert(0,t,'0'); else a.insert(0,-t,'0'); //模拟竖式加法 int ta,tb,tsum,tres,tc=0; for(int i=a.length()-1;i>=0;i--) { ta = a[i]-'0'; tb = b[i]-'0'; tsum = ta+tb+tc; tres = tsum%10; //本位和 tc = tsum/10; //进位 res.insert(0,1,tres+'0'); } if(tc!=0) res.insert(0,1,tc+'0'); //最高位进位 //去除多余前导0 int i=0; while(res[i]=='0') i++; res = res.substr(i) == "" ? "0" : res.substr(i); return res; } int main() { string a,b; cin>>a>>b; cout<<add(a,b); return 0; }