前言:
题目:P1009 [NOIP1998 普及组] 阶乘之和
虽然这题 n <= 50,但阶乘本身就是很大的数,何况该题求的是阶乘之和,这就必须用到高精度了,高精度乘法和高精度加法
前置知识:
P1601 A B Problem(高精)
https://www.luogu.com.cn/problem/P1601
代码语言:javascript复制#include <iostream>
#include <cstring>
#include <algorithm>
#include <vector>
#include <cmath>
#include <unordered_map>
#include <unordered_set>
#include <map>
#include <set>
#include <queue>
#include <stack>
#include <deque>
#include <functional>
#include <climits>
#define quickio ios::sync_with_stdio(false),cin.tie(0),cout.tie(0);
#define endl "n"
using namespace std;
typedef long long ll;
//a b = c
int A[505];//第一个加数的数组
int B[505];//第二个加数的数组
int C[506];//和的数组
int len_c;
void Add()
{
for (int i = 0; i < len_c; i )
{
C[i] = A[i] B[i];
C[i 1] = C[i] / 10;
C[i] %= 10;
}
if (C[len_c])
len_c ;
}
int main()
{
string a, b;//注意用字符串读入
cin >> a >> b;
int len_a = a.size(), len_b = b.size();
len_c = max(len_a, len_b);
for (int i = 0; i < len_a; i )
A[len_a - 1 - i] = a[i] - '0';//注意 - ‘0’,且逆序存
for (int i = 0; i < len_b; i )
B[len_b - 1 - i] = b[i] - '0';//注意 - ‘0’
Add();
for (int i = 0; i < len_c; i )
cout << C[len_c - 1 - i];//注意逆序输出,因为存的时候是逆序的
return 0;
}
P1303 A*B Problem
https://www.luogu.com.cn/problem/P1303
代码语言:javascript复制int c[5000];
int len_a, len_b, len_c;
void mul(int a[], int b[])
{
for (int i = 0; i < len_a; i )
{
for (int j = 0; j < len_b; j )
{
c[i j] = a[i] * b[j];//注意是 =
c[i j 1] = c[i j] / 10;
c[i j] = c[i j] % 10;
}
}
while (len_c > 1 && c[len_c - 1] == 0)
//注意要len_c > 1,如果乘积为0,就会一直减下去,最后什么都不输出,这是错误的
//注意是c[len_c - 1] == 0
len_c--;
}
int main()
{
string a, b;
cin >> a >> b;
len_a = a.size(), len_b = b.size();
len_c = len_a len_b;
int aarr[2005], barr[2005];
//倒着存
for (int i = 0; i < len_a; i )
aarr[i] = a[len_a - 1 - i] - '0';//记得 - '0'
for (int i = 0; i < len_b; i )
barr[i] = b[len_b - 1 - i] - '0';
mul(aarr, barr);
//cout << len_c << endl;
//倒着输出
for (int i = 0; i < len_c; i )
cout << c[len_c - 1 - i];
return 0;
}
AC代码:
P1009 [NOIP1998 普及组] 阶乘之和
注意该题数据一定会很大,要用到高精度
代码语言:javascript复制#include <iostream>
#include <cstring>
#include <algorithm>
#define quickio ios::sync_with_stdio(false),cin.tie(0),cout.tie(0);
#define endl "n"
using namespace std;
typedef long long ll;
const int N = 1005;
//a*b=c
int A[N];//i
int C[N];
int jc[N][N];//阶乘数组
int ans[N][N];//答案数组
int main()
{
int n;
cin >> n;
jc[0][0] = 1;//0的阶乘 = 1
int len_a = 1, len_b = 1, len_c = len_a len_b, len_ans;
jc[1][0] = 1;
ans[1][0] = 1;
for (int i = 2; i <= n; i )
{
//得到i的数组:A
int temp = i;
len_a = 0;
for (int j = 0; temp; j )
{
A[j] = temp % 10;
temp /= 10;
len_a ;
}
//高精度乘法:求阶乘(i * (i - 1)!)
len_c = len_b len_a;
for (int j = 0; j < len_a/*i的长度*/; j )
{
for (int k = 0; k < len_b/*上一个阶乘的长度*/; k )
{
jc[i][j k] = A[j] * jc[i - 1][k];//i * (i - 1)!
jc[i][j k 1] = jc[i][k j] / 10;
jc[i][j k] %= 10;
}
}
while (len_c > 1 && jc[i][len_c - 1] == 0)
len_c--;
len_b = len_c;//更新阶乘长度
//高精度加法:求答案(ans[i-1] jc[i])
len_ans = max(len_ans, len_c);
for (int j = 0; j < len_ans; j )
{
ans[i][j] = ans[i - 1][j] jc[i][j];
ans[i][j 1] = ans[i][j] / 10;
ans[i][j] %= 10;
}
if (ans[i][len_ans])
len_ans ;
}
for (int i = 0; i < len_ans; i )//逆序输出答案
cout << ans[n][len_ans - 1 - i];
return 0;
}