对于大数的输入需要用到字符串的输入,可以在输入后对数据进行转换
int a[1005],b[1005];
char s1[1005],s2[1005];
for (int i=0;i<strlen(s1);i++)
{
a[i]=s1[strlen(s1)-i-1]-'0';//进行头尾倒置,方便后续数据计算
}
for (int i=0;i<strlen(s2);i++)
{
b[i]=s2[strlen(s2)-i-1]-'0';
}
高精度加法
A + B Problem II
时间限制(普通/Java):1000MS/10000MS 内存限制:65536KByte
描述
I have a very simple problem for you. Given two integers A and B, your job is to calculate the Sum of A + B.
输入
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.
输出
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.
样例输入
2
1 2
112233445566778899 998877665544332211
样例输出
Case 1:
1 + 2 = 3
Case 2:
112233445566778899 + 998877665544332211 = 1111111111111111110
该题描述为两个长度不大于1000的数相加,而unsigned long也只有20位,对于这类大数据的相加需要用到字符串的存储,并对字符串进行处理与运算
数据类型 | 数据范围 |
---|---|
unsigned long | 0 ~ 1844 6744 0737 0955 1615 (1844*10^16) |
代码
#include <bits/stdc++.h>
using namespace std;
int a[1005], b[1005], ans[1005];//
int main()
{
char s1[1005], s2[1005];
int n;
scanf("%d", &n);
for (int k = 1; k <= n; k++)
{
printf("Case %d:\n", k);
scanf("%s%s", s1, s2);
//对字符串处理成数字存储,方便后续相加处理
int la = strlen(s1), lb = strlen(s2);
for (int i = 0; i < la; i++)
{
a[i] = s1[la - i - 1] - '0';//倒序处理
}
for (int i = 0; i < lb; i++)
{
b[i] = s2[lb - i - 1] - '0';
}
//进行数据相加的处理,从最后一位开始相加
int lc = la > lb ? la : lb;
for (int i = 0; i < lc; i++)
{
ans[i] += a[i] + b[i];
ans[i + 1] += ans[i] / 10;//进位操作
ans[i] %= 10;
}
//判断最后一位是否存在
if (ans[lc])
{
lc++;
}
printf("%s + %s = ", s1, s2);
for (int i = lc - 1; i >= 0; i--)
{
printf("%d", ans[i]);
}
if (k != n)
{
printf("\n");
}
printf("\n");
//初始化为零
memset(ans,0,sizeof(ans));
memset(a,0,sizeof(a));
memset(b,0,sizeof(b));
}
}
高精度减法
两数相减
时间限制(普通/Java):1000MS/10000MS 内存限制:65536KByte
描述
给定两个自然数A和B,求A-B的值。
输入
输入数据有多组,第一行为测试数据的组数n,下面的n行中,每行有两个数分别表示A,B。A和B的最大位数不超过1000位。
输出
输出A-B的值。
样例输入
3
1 1
10 2
1000 2000
样例输出
0
8
-1000
代码
#include <bits/stdc++.h>
using namespace std;
int a[1005],b[1005],ans[1005];
int la,lb,lc;
//进行相减后结果正负的判断
bool cmp(int a[],int b[])
{
if (la!=lb)
{
return la>lb;
}
for (int i=la-1;i>-1;i--)
{
if (a[i]!=b[i])
{
return a[i]>b[i];//防止出现-0的情况
}
}
return true;
}
int main()
{
int n;
scanf("%d",&n);
char s1[1005]={0},s2[1005]={0};
while (n--)
{
getchar();
scanf("%s %s",s1,s2);
la=strlen(s1),lb=strlen(s2),lc=la>lb?la:lb;
for (int i=0;i<la;i++)
{
a[i]=s1[la-i-1]-'0';
}
for (int i=0;i<lb;i++)
{
b[i]=s2[lb-i-1]-'0';
}
if (!cmp(a,b))
{
swap(a,b);//交换函数,交换两个数组
printf("-");
}
for (int i=0;i<lc;i++)
{
if (a[i]<b[i])
{
a[i+1]--;//进位
a[i]+=10;
}
ans[i]=a[i]-b[i];
}
while (lc && ans[lc]==0)
{
lc--;
}
for (int i=lc;i>=0;i--)
{
printf("%d",ans[i]);
}
printf("\n");
}
}
高精度乘法
高精度乘法
时间限制(普通/Java):1000MS/3000MS 内存限制:65536KByte
描述
输入两个高精度非负整数M和N(M和N均小于100位)。求这两个高精度数的积。
输入
输入两个高精度非负整数M和N。
输出
求这两个高精度数的积,结果不含前导0。
样例输入
36
3
样例输出
108
代码
#include <bits/stdc++.h>
using namespace std;
int a[105],b[105],ans[10005];
int la,lb,lc;
int main()
{
char s1[105],s2[105];
scanf("%s %s",s1,s2);
la=strlen(s1),lb=strlen(s2);
for (int i=0;i<la;i++)
{
a[i]=s1[la-i-1]-'0';
}
for (int i=0;i<lb;i++)
{
b[i]=s2[lb-i-1]-'0';
}
lc=la+lb;
for (int i=0;i<la;i++)
{
for (int j=0;j<lb;j++)
{
ans[i+j]+=a[i]*b[j];//累加乘积
ans[i+j+1]+=ans[i+j]/10;//进位
ans[i+j]%=10;//求余
}
}
while (lc && ans[lc]==0)//处理前导零
{
lc--;
}
for (int i=lc;i>-1;i--)
{
printf("%d",ans[i]);
}
printf("\n");
}
高精度除法
A/B Problem
题目描述
输入两个整数 a , b a,b a,b,输出它们的商。
输入格式
两行,第一行是被除数,第二行是除数。
输出格式
一行,商的整数部分。
样例 #1
** 样例输入 #1**
10
2
** 样例输出 #1**
5
提示
0
≤
a
≤
1
0
5000
0\le a\le 10^{5000}
0≤a≤105000,
1
≤
b
≤
1
0
9
1\le b\le 10^9
1≤b≤109。
高精度除法可以分为高精除以低精度,该题为高精除低精
高精度除以低精度
#include <bits/stdc++.h>
using namespace std;
int a[100005],ans[100005];
long long b;
int la,lc;
int main()
{
char s1[100005];
scanf("%s %lld",s1,&b);
lc=la=strlen(s1);
for (int i=0;i<la;i++)
{
a[i]=s1[la-i-1]-'0';
}
long long r=0;
for (int i=la-1;i>-1;i--)
{
r=r*10+a[i];//被除数
ans[la-i-1]=r/b;//存商
r%=b;//求余
}
reverse(ans,ans+lc);
//去除前置零
while (lc && ans[lc]==0)
{
lc--;
}
for (int i=lc;i>-1;i--)
{
printf("%d",ans[i]);
}
printf(" %d\n",r);
}
高精除以高精将会不久后补全