好久没写高精度的题了,老是说高精度高精度,到底什么是高精度呢,看一下下面这道题再试着用常规方法去做一做,然后遇到报错,相信你就会明白什么是高精度以及其用处,题目转载自洛谷阶乘之和
[NOIP1998 普及组] 阶乘之和
题目描述
用高精度计算出 S = 1 ! + 2 ! + 3 ! + ⋯ + n ! S = 1! + 2! + 3! + \cdots + n! S=1!+2!+3!+⋯+n!( n ≤ 50 n \le 50 n≤50)。
其中 !
表示阶乘,定义为
n
!
=
n
×
(
n
−
1
)
×
(
n
−
2
)
×
⋯
×
1
n!=n\times (n-1)\times (n-2)\times \cdots \times 1
n!=n×(n−1)×(n−2)×⋯×1。例如,
5
!
=
5
×
4
×
3
×
2
×
1
=
120
5! = 5 \times 4 \times 3 \times 2 \times 1=120
5!=5×4×3×2×1=120。
输入格式
一个正整数 n n n。
输出格式
一个正整数 S S S,表示计算结果。
样例 #1
样例输入 #1
3
样例输出 #1
9
提示
【数据范围】
对于
100
%
100 \%
100% 的数据,
1
≤
n
≤
50
1 \le n \le 50
1≤n≤50。
常规方法写,全部爆红,输入几个小点的数,全过,这时候可以想到是高精度了
思路开始:
把阶乘求和拆分为3步:
1.求阶乘:
void c(int y){
int f=0;
for(int i=100;i>-1;i--){
s[i]=s[i]*y+f;
f=s[i]/10;
s[i]%=10;
}
}
y为阶乘数,是的第100号元素为1(因为所有数的阶乘从1乘起,放到100位是因为便于数组输出,我们知道"12345"存入数组之后输出时应倒序)
2.求和
来一个以数组存储的阶乘结果就加到要输出的数组中
void h(){
int w=0;
for(int i=100;i>-1;i--){
a[i]=a[i]+s[i]+w;
w=a[i]/10;
a[i]%=10;
}
}
3.处理输出
100的数组空间显然过大,会有不少零位于数组前段,比如1的阶乘加2的阶乘,为3
结果数组:0000000…00003,有99个前置0,显然要处理一下:
void sccl(){
int first_no_zero;
for(int i=0;i<101;i++){
if(a[i]!=0){
first_no_zero=i;
for(int j=first_no_zero;j<101;j++){
cout<<a[j];
}
break;
}
}
}
附上全代码:
#include<iostream>
using namespace std;
int s[101]={0};int a[101]={0};
void c(int y){
int f=0;
for(int i=100;i>-1;i--){
s[i]=s[i]*y+f;
f=s[i]/10;
s[i]%=10;
}
}
void h(){
int w=0;
for(int i=100;i>-1;i--){
a[i]=a[i]+s[i]+w;
w=a[i]/10;
a[i]%=10;
}
}
void sccl(){
int first_no_zero;
for(int i=0;i<101;i++){
if(a[i]!=0){
first_no_zero=i;
for(int j=first_no_zero;j<101;j++){
cout<<a[j];
}
break;
}
}
}
int main(){
int n;
cin>>n;
s[100]=1;
a[100]=1;
for(int i=2;i<n+1;i++){
c(i);
h();
}
sccl();
return 0;
}
典型的高精度问题,处理的数据大于long long,希望对你有帮助!