题目描述
高精度加法,相当于 a+b problem,不用考虑负数。
输入格式
分两行输入。a,b≤10500。
输出格式
输出只有一行,代表 a+b 的值。
输入输出样例
输入 #1复制
1
1
输出 #1复制
2
输入 #2复制
1001
9099
输出 #2复制
10100
说明/提示
20% 的测试数据,0≤a,b≤1e9;
40% 的测试数据,0≤a,b≤1e18。
为了方便从低位到高位逐位计算,先将两个字符串反转。
从最低位开始,逐位相加,并处理进位。
如果最后还有进位,将其写入结果的最高位。
反转回正常顺序后,去除结果中的前导零。
如果结果为全零,返回”0“否则返回有效部分。
源代码:
#include<iostream>
#include<string>
#include<algorithm>
using namespace std;
// 反转字符串函数
string rever(string str) {
return string(str.rbegin(), str.rend()); // 使用反向迭代器反转字符串
}
// 大数加法函数
string add(string a, string b) {
int x, carry = 0; // x 用于存储当前位的和,carry 用于存储进位
a = rever(a); // 反转字符串 a,方便从低位到高位计算
b = rever(b); // 反转字符串 b
string c; // 用于存储结果
c.resize(max(a.length(), b.length()) + 1, '0'); // 预分配结果空间,多一位用于可能的最高位进位
a.resize(max(a.length(), b.length()) + 1, '0'); // 补齐 a 的长度,避免越界
b.resize(max(a.length(), b.length()) + 1, '0'); // 补齐 b 的长度
for (int i = 0; i < max(a.length(), b.length()); i++) {
x = a[i] - '0' + b[i] - '0' + carry; // 计算当前位的和(包括进位)
carry = x / 10; // 计算进位
c[i] = (x % 10) + '0'; // 存储当前位的结果
}
if (carry > 0)
c[max(a.length(), b.length())] = carry + '0'; // 如果最后还有进位,写入最高位
c = rever(c); // 反转回正常顺序
int start = 0;
while (start < max(a.length(), b.length()) && c[start] == '0')
start++; // 去除前导零
c = c.substr(start); // 截取有效部分
if (c.empty())
return "0"; // 如果结果为全零,返回 "0"
return c;
}
int main() {
string a, b;
cin >> a >> b;
cout << add(a, b);
return 0;
}
题目背景
高精度乘法模板题。
题目描述
给出两个非负整数,求它们的乘积。
输入格式
输入共两行,每行一个非负整数。
输出格式
输出一个非负整数表示乘积。
输入输出样例
输入 #1复制
1
2
输出 #1复制
2
说明/提示
每个非负整数不超过 1e2000。
为了方便从低位到高位逐位计算,先将两个字符串反转。
从最低位开始,逐位相乘,并处理进位。
将每一位的乘积累加到结果字符串的对应位置。
如果最后还有进位,将其写入结果的最高位。
反转回正常顺序后,去除结果中的前导零。
如果结果为全零,返回”0”,否则返回有效部分。
源代码:
#include<iostream>
#include<string>
#include<algorithm>
using namespace std;
// 反转字符串函数
string rever(string str) {
return string(str.rbegin(), str.rend()); // 使用反向迭代器反转字符串
}
// 大数乘法函数
string mul(string a, string b) {
int x, carry; // x 用于存储当前位的乘积,carry 用于存储进位
a = rever(a); // 反转字符串 a,方便从低位到高位计算
b = rever(b); // 反转字符串 b
string c; // 用于存储结果
c.resize(a.length() + b.length(), '0'); // 预分配结果空间,长度为 a 和 b 的长度之和
for (int i = 0; i < a.length(); i++) {
carry = 0; // 每次外层循环开始时,进位初始化为 0
for (int j = 0; j < b.length(); j++) {
x = (a[i] - '0') * (b[j] - '0') + (c[i + j] - '0') + carry; // 计算当前位的乘积和进位
carry = x / 10; // 计算新的进位
c[i + j] = (x % 10) + '0'; // 存储当前位的结果
}
if (carry > 0)
c[i + b.length()] = (c[i + b.length()] - '0' + carry) + '0'; // 处理最高位进位
}
c = rever(c); // 反转回正常顺序
int start = 0;
while (start < c.length() && c[start] == '0')
start++; // 去除前导零
c = c.substr(start); // 截取有效部分
if (c.empty())
return "0"; // 如果结果为全零,返回 "0"
return c;
}
int main() {
string a, b;
cin >> a >> b;
cout << mul(a, b);
return 0;
}
题目描述
用高精度计算出 S=1!+2!+3!+⋯+n!(n≤50)。
其中 !
表示阶乘,定义为 n!=n×(n−1)×(n−2)×⋯×1。例如,5!=5×4×3×2×1=120。
输入格式
一个正整数 n。
输出格式
一个正整数 S,表示计算结果。
输入输出样例
输入 #1复制
3
输出 #1复制
9
说明/提示
【数据范围】
对于 100% 的数据,1≤n≤50。
前面已经介绍了高精度乘法和加法,这里就直接使用上面的乘法和加法函数,只需要再写一个求阶乘的函数,再通过循环求和就行了
源代码:
#include<iostream>
#include<string>
#include<algorithm>
using namespace std;
int n;
string rever(string str) {
return string(str.rbegin(), str.rend());
}
string mul(string a, string b);
string add(string a, string b);
string jc(int n) {
string a = "1";
for (int i = 0; i < n; i++) {
string b = to_string(i + 1);//将整形或者浮点型转换成对应的字符串
a = mul(a, b);
}
return a;
}
int main() {
cin >> n;
string c = "0";
for (int i = 1; i <= n; i++)
c = add(c, jc(i));
cout << c;
return 0;
}
string mul(string a, string b) {
int x, carry;
a = rever(a);
b = rever(b);
string c;
c.resize(a.length() + b.length(), '0');
for (int i = 0; i < a.length(); i++) {
carry = 0;
for (int j = 0; j < b.length(); j++) {
x = (a[i] - '0') * (b[j] - '0') + (c[i + j] - '0') + carry;
carry = x / 10;
c[i + j] = (x % 10) + '0';
}
if (carry > 0)
c[i + b.length()] = (c[i + b.length()] - '0' + carry) + '0';
}
c = rever(c);
int start = 0;
while (start < c.length() && c[start] == '0')
start++;
c = c.substr(start);
if (c.empty())
return "0";
return c;
}
string add(string a, string b) {
int x, carry = 0;
a = rever(a);
b = rever(b);
string c;
c.resize(max(a.length(), b.length()) + 1, '0');
a.resize(max(a.length(), b.length()) + 1, '0');
b.resize(max(a.length(), b.length()) + 1, '0');
for (int i = 0; i < max(a.length(), b.length()); i++) {
x = a[i] - '0' + b[i] - '0' + carry;
carry = x / 10;
c[i] = (x % 10) + '0';
}
if (carry > 0)
c[max(a.length(), b.length())] = carry + '0';
c = rever(c);
int start = 0;
while (start < max(a.length(), b.length()) && c[start] == '0')
start++;
c = c.substr(start);
return c;
}