P1009_阶乘之和(NOIP1998 普及组)
Description
用高精度计算出 S = 1 ! + 2 ! + 3 ! + ⋯ + n ! ( n ≤ 50 ) 。 S = 1! + 2! + 3! +\cdots + n!(n \le 50)。 S=1!+2!+3!+⋯+n!(n≤50)。
其中“!”表示阶乘,例如: 5 ! = 5 × 4 × 3 × 2 × 1 。 5! = 5 \times 4 \times 3 \times 2 \times 1。 5!=5×4×3×2×1。
Input
一个正整数 n。
Output
一个正整数S,表示计算结果。
Sample Input
3
Sample Output
9
这题从1的阶乘加到50的阶乘,得出的是65位的整数,显然无法用已知的数据类型来做,所以只能用高精度( 学 习 传 送 门 ← \underleftarrow{学习传送门} 学习传送门)来表示,以下是代码。
#include <cstdio>
#include <cstring>
using namespace std;
struct bign{
int d[1000];
int len;
bign(){
memset(d, 0, sizeof(d));
len = 0;
}
};
bign add(bign a, bign b){
bign c;
int carry = 0;
for(int i = 0; i < a.len || i < b.len; i++){
int t = a.d[i] + b.d[i] + carry;
c.d[c.len++] = t % 10;
carry = t /10;
}
if(carry != 0){
c.d[c.len++] = carry;
}
return c;
}
bign mul(bign a, int b){
bign c;
int carry = 0;
for(int i = 0; i < a.len; i++){
int t = a.d[i] * b + carry;
c.d[c.len++] = t % 10;
carry = t / 10;
}
while(carry != 0){
c.d[c.len++] = carry % 10;
carry /= 10;
}
return c;
}
void print(bign a){
for(int i = a.len - 1; i >= 0; i--){
printf("%d", a.d[i]);
}
}
int main(){
int n;
scanf("%d",&n);
bign sum, a;
a.d[0] = 1;
a.len = 1;
for(int i = 1; i <= n; i++){
a = mul(a, i);
sum = add(sum, a);
}
print(sum);
return 0;
}
如果数据没有到50而是到20,我们就可以用正常的数据类型来表示,这个就简单许多了,直接从1枚举累乘累加到n就行了,以下是代码。
#include <cstdio>
using namespace std;
int main(){
int n;
unsigned long long ans = 0, a = 1;
scanf("%d",&n);
for(int i=1;i<=n;i++){
a *= i;
ans += a;
}
printf("%lld",ans);
return 0;
}
有问题欢迎私信我!