题目 1014: [编程入门]阶乘求和
时间限制: 3s 内存限制: 192MB
题目描述
求Sn=1!+2!+3!+4!+5!+…+n!之值,其中n是一个数字(n不超过20)。
输入格式
n
输出格式
Sn的值
样例输入
5
样例输出
153
解答
错误解答
#define _CRT_SECURE_NO_WARNINGS
#include<stdio.h>
double cal(int num);
int main() {
int n;
double sum = 0;
scanf("%d", &n);
for (int i = 1; i <= n; i++) {
double mid = cal(i);
sum += mid;
}
printf("%.0lf", sum);
return 0;
}
double cal(int num) {
double font = 1.0;
for (int i = 1; i <= num; i++) {
font *= i;
}
return font;
}
正确解答
#define _CRT_SECURE_NO_WARNINGS
#include<stdio.h>
long long int cal(int num);
int main() {
int n;
long long int sum = 0;
scanf("%d", &n);
for (int i = 1; i <= n; i++) {
long long int mid = cal(i);
sum += mid;
}
printf("%lu", sum);
return 0;
}
long long int cal(int num) {
if (num == 1) return 1;
return num * cal(num - 1);
}
优质解答
#define _CRT_SECURE_NO_WARNINGS
#include<stdio.h>
int main(void)
{
unsigned long int Sn = 0, An = 1; //或long long类型也行
int n, i;
scanf("%d", &n);
for (i = 1; n >= i; i++)
{
Sn = Sn + An;
An = (i + 1) * An;
}
printf("%lu", Sn); //如果上面声明的是long long类型,这里占位符相应也就是%lld
return 0;
}
注:本篇使用vs2022编译
解析与反思
错误解答中没有考虑到数据类型问题,在更改为正确解答之后,仍然不是最优解。有两个问题,其一是没有进行记忆和存储,其二是用到了栈,虽然递归看上去减少了代码量,但更耗费时间。
本题难点在于两个地方,第一是数据类型问题,第二就是减少时间复杂度。计算n的阶乘,没必要每个值都从1开始计算,应该存储上一次计算结果之后乘以本次的值。将中间值的初始化放在循环之外进行,可以避免初始化为1 的问题,也不需要使用函数。
总结
本题较为简单,n<=20的范围限制了数据范围,如果n的取值范围再大一些,将考虑高精度的问题。