2023年蓝桥杯省赛——阶乘求和
题目链接:9.阶乘求和 - 蓝桥云课 (lanqiao.cn)
思路
难点:关于阶乘的数学问题
首先我们需要了解阶乘的一个特性。我来带着大家算一遍
如果你计算1!~ 4!的阶乘会发现并没有什么奇怪的,但是随着计算的深入就可以费县一些规律
下面是1!~30!的结果
- 1的阶乘 = 1
- 2的阶乘 = 2
- 3的阶乘 = 6
- 4的阶乘 = 24
- 5的阶乘 = 120
- 6的阶乘 = 720
- 7的阶乘 = 5040
- 8的阶乘 = 40,320
- 9的阶乘 = 362,880
- 10的阶乘 = 3,628,800
- 11的阶乘 = 39,916,800
- 12的阶乘 = 479,001,600
- 13的阶乘 = 6,227,020,800
- 14的阶乘 = 87,178,291,200
- 15的阶乘 = 1,307,674,368,000
- 16的阶乘 = 20,922,789,888,000
- 17的阶乘 = 355,687,428,096,000
- 18的阶乘 = 6,402,373,705,728,000
- 19的阶乘 = 121,645,100,408,832,000
- 20的阶乘 = 2,432,902,008,176,640,000
- 21的阶乘 = 51,090,942,171,709,440,000
- 22的阶乘 = 1,124,000,727,777,607,680,000
- 23的阶乘 = 25,852,016,738,884,976,640,000
- 24的阶乘 = 620,448,401,733,239,439,360,000
- 25的阶乘 = 15,511,210,043,330,985,984,000,000
- 26的阶乘 = 403,291,461,126,605,636,584,960,000
- 27的阶乘 = 10,888,869,450,418,352,160,768,000,000
- 28的阶乘 = 304,888,344,611,713,860,501,504,000,000
- 29的阶乘 = 8,841,761,993,739,700,852,282,368,000,000
- 30的阶乘 = 265,252,859,812,191,058,636,308,480,000,000
所以发现了没,尾部的0是不是越来越多,我只有一个问题。当到一个阶乘的时候,尾部全部是0,那么他和其他值相加,是不是不影响尾部9位数的答案。既然如此我们就拿下了,发现没有,蓝桥杯的填空题全部都是数学问题。
代码思路
解释一下每一行代码的作用:
long sum = 0L;
:定义了一个长整型变量sum,初始值为0,用于存储阶乘和。long jc = 1L;
:定义了一个长整型变量jc,初始值为1,用于存储阶乘的计算结果。for (int i = 1; i > 0; i++) {}
:定义了一个无限循环,循环变量i从1开始,每次循环后i加1。jc *= i;
:计算i的阶乘,结果保存在jc中。jc = jc % 1000000000L;
:运算符%返回余数,这句代码将jc限制在了后九位数字。sum += jc;
:将jc的值加到sum中。sum = sum % 1000000000L;
:同样将sum限制在了后九位数字。if (jc % 1000000000L == 0) {}
:这个if语句用于检查jc的值是否已经后九位全部为0了。如果是,那么就输出sum的值并跳出循环。System.out.println(sum);
:输出sum的值。break;
:跳出循环。
所以,这段代码实现的是:从1开始,计算每一个数字的阶乘,并将这些阶乘的和(只保留之后九位)输出出来,直到阶乘的结果的后九位全部为0。
代码实现
Java
import java.util.Scanner;
// 1:无需package
// 2: 类名必须Main, 不可修改
public class Main {
public static void main(String[] args) {
long sum = 0L;
long jc = 1L;
for (int i = 1; i > 0; i++) {
// 首先是得到该阶段的阶乘的值
jc *= i;
// 我们的目标只是后九位,其他的位数是多少无关
jc = jc % 1000000000L;
// 将后九位加和
sum += jc;
// 为了防止进位导致的问题,sum也只要后九位
sum = sum % 1000000000L;
// 由阶乘的特性可知,阶乘变大后尾部的0会越来越多
// 最终知道后九位全部为0,这时就不影响S的后九位了
if (jc % 1000000000L == 0) {
System.out.println(sum);
break;
}
}
}
}
C++
#include <iostream>
using namespace std;
int main() {
unsigned long long sum = 0;
unsigned long long jc = 1;
for (int i = 1;; i++) {
jc *= i;
jc = jc % 1000000000;
sum += jc;
sum = sum % 1000000000;
if (jc % 1000000000 == 0) {
cout << sum << endl;
break;
}
}
return 0;
}
结束了
总结
拿下!!!
٩(๑❛ᴗ❛๑)۶٩(๑❛ᴗ❛๑)۶٩(๑❛ᴗ❛๑)۶٩(๑❛ᴗ❛๑)۶٩(๑❛ᴗ❛๑)۶٩(๑❛ᴗ❛๑)۶