2023年蓝桥杯省赛——阶乘求和

题目链接:9.阶乘求和 - 蓝桥云课 (lanqiao.cn)

思路

难点:关于阶乘的数学问题

首先我们需要了解阶乘的一个特性。我来带着大家算一遍

如果你计算1!~ 4!的阶乘会发现并没有什么奇怪的,但是随着计算的深入就可以费县一些规律

下面是1!~30!的结果

  1. 1的阶乘 = 1
  2. 2的阶乘 = 2
  3. 3的阶乘 = 6
  4. 4的阶乘 = 24
  5. 5的阶乘 = 120
  6. 6的阶乘 = 720
  7. 7的阶乘 = 5040
  8. 8的阶乘 = 40,320
  9. 9的阶乘 = 362,880
  10. 10的阶乘 = 3,628,800
  11. 11的阶乘 = 39,916,800
  12. 12的阶乘 = 479,001,600
  13. 13的阶乘 = 6,227,020,800
  14. 14的阶乘 = 87,178,291,200
  15. 15的阶乘 = 1,307,674,368,000
  16. 16的阶乘 = 20,922,789,888,000
  17. 17的阶乘 = 355,687,428,096,000
  18. 18的阶乘 = 6,402,373,705,728,000
  19. 19的阶乘 = 121,645,100,408,832,000
  20. 20的阶乘 = 2,432,902,008,176,640,000
  21. 21的阶乘 = 51,090,942,171,709,440,000
  22. 22的阶乘 = 1,124,000,727,777,607,680,000
  23. 23的阶乘 = 25,852,016,738,884,976,640,000
  24. 24的阶乘 = 620,448,401,733,239,439,360,000
  25. 25的阶乘 = 15,511,210,043,330,985,984,000,000
  26. 26的阶乘 = 403,291,461,126,605,636,584,960,000
  27. 27的阶乘 = 10,888,869,450,418,352,160,768,000,000
  28. 28的阶乘 = 304,888,344,611,713,860,501,504,000,000
  29. 29的阶乘 = 8,841,761,993,739,700,852,282,368,000,000
  30. 30的阶乘 = 265,252,859,812,191,058,636,308,480,000,000
 

        

        所以发现了没,尾部的0是不是越来越多,我只有一个问题。当到一个阶乘的时候,尾部全部是0,那么他和其他值相加,是不是不影响尾部9位数的答案。既然如此我们就拿下了,发现没有,蓝桥杯的填空题全部都是数学问题。

代码思路

解释一下每一行代码的作用:

  1. long sum = 0L;:定义了一个长整型变量sum,初始值为0,用于存储阶乘和。
  2. long jc = 1L;:定义了一个长整型变量jc,初始值为1,用于存储阶乘的计算结果。
  3. 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;
}
 

结束了

总结

拿下!!!

٩(๑❛ᴗ❛๑)۶٩(๑❛ᴗ❛๑)۶٩(๑❛ᴗ❛๑)۶٩(๑❛ᴗ❛๑)۶٩(๑❛ᴗ❛๑)۶٩(๑❛ᴗ❛๑)۶