求 1! + 2! + 3! + … + 202320232023! ,总和的末尾九位数字。


【学习的细节是欢悦的历程】


  自学并不是什么神秘的东西,一个人一辈子自学的时间总是比在学校学习的时间长,没有老师的时候总是比有老师的时候多。
            —— 华罗庚


等风来,不如追风去……


1!+ 2! + 3! + ... + 202320232023!
阶 乘 求 和
(求阶乘总和的末尾九位数字)


本文质量分:

90
本文地址: https://blog.csdn.net/m0_57158496/article/details/130472920

CSDN质量分查询入口:http://www.csdn.net/qc


目 录


◆ 阶乘求和


1、题目描述


  令 S = 1!+ 2! + 3! + … + 202320232023! ,求 S 的末尾 9 位数字。


  • 提示:答案首位不为 0 。

(问题来源于 CSDN 问答社区提问“问题”)。



回页目录

2、“简单”解题思路


  这题目“超简单”,写一个“求阶乘”的子模块,循环调用子模块求阶乘序列总和就好。

2.1 求阶乘函数

  • Python 代码

def factorail(n):

    if n in (0, 1):
        return 1

    result = 1

    for i in range(2, n+1):
        result *= i

    return result

  • 这里就不用“递归算法”求阶乘,改用效率更高的 for 循环。

2.2 for 遍历轮询求阶乘序列总和


start_sec = time()
n = 202320232023

result = 0
for i in range(1, n + 1):
    print(' '*50, end='\r')
    print(f"{' '*(i%40)}正在计算……", end='\r') 
    result += factorail(i)


2.3 截取总和末尾九位数字


print(f"\n{str(result)[-9:]}\n\n{f' 程序用时 {time() - start_sec:.4f} 秒 ':~^45}\n")

  • 这看似无可挑剔的“算法”,却出不了结果。原因是 1~202320232023 那么大序列的阶乘总和,是一时半会演算不出来的。还有可能发生“内存溢出”的情况。
    (我缘于好奇,让我的前面那段代码在 termux 上跑了几个小时,都还在“演算中……”,只好手动按下 Ctrl + c ,kill 了进程。)


回页目录

3、探究“捷径”


大神解题思路:

  阶乘增加很快,45! 的末九位数就全都为 0 了(当然是 Pythond 打印看到的),因为我们只需要末九位数字,所以后面任意的 + n! 都不会对 1! + 2! + … + 202320232023! 的总和最后九位数字造成影响,枚举到 + 45! 即可。答案为 420940313 。


if __name__ == '__main__':
    for i in range(1, 4):
        print(factorail(i))


input() 

  • 代码运行输出 1!~45! :

/sdcard/qpython $ python 000.py
1
2
6
24
120
720
5040
40320
362880
3628800
39916800
479001600
6227020800
87178291200
1307674368000
20922789888000
355687428096000
6402373705728000
121645100408832000
2432902008176640000
51090942171709440000
1124000727777607680000
25852016738884976640000
620448401733239439360000
15511210043330985984000000
403291461126605635584000000
10888869450418352160768000000
304888344611713860501504000000
8841761993739701954543616000000
265252859812191058636308480000000
8222838654177922817725562880000000
263130836933693530167218012160000000
8683317618811886495518194401280000000
295232799039604140847618609643520000000
10333147966386144929666651337523200000000
371993326789901217467999448150835200000000
13763753091226345046315979581580902400000000
523022617466601111760007224100074291200000000
20397882081197443358640281739902897356800000000
815915283247897734345611269596115894272000000000
33452526613163807108170062053440751665152000000000
1405006117752879898543142606244511569936384000000000
60415263063373835637355132068513997507264512000000000
2658271574788448768043625811014615890319638528000000000
119622220865480194561963161495657715064383733760000000000

  • 由上面的打印可以看到,45! 的末尾九位数字就开始全 0 了。


start_sec = time()
n = 202320232023

result = 0
for i in range(1, 46):
    print(' '*50, end='\r')
    print(f"{' '*(i%40)}正在计算……", end='\r') 
    temp = factorail(i)

    '''if str(temp)[-9:] == '0'*9:
        break'''

    result += temp
    #print(i, str(result)[-9:], factorail(i))

if __name__ == '__main__':
    print(f"\n{str(result)[-9:]}\n\n{f' 程序用时 {time() - start_sec:.4f} 秒 ':~^45}\n")

在这里插入图片描述
  据其上思路,我们就把 for 循环定到 45 就好。但,这是在您熟悉 1~45 阶乘的情况下,要是不明白这“技巧”哩?🤨



回页目录

4、算法优化


4.1 总和的末尾九位数字连续十次相同


  总和后九位数字连续十次不变,说明已经遍历轮询到 n! 后九位数字全部是 0 了,可以退出循环,输出结果。

# 总和后九位数字连续十次不变
start_sec = time()
n = 202320232023

result = flag = 0
tail = None
for i in range(1, n + 1):
    print(' '*50, end='\r')
    print(f"{' '*(i%40)}正在计算……", end='\r') 
    result += factorail(i)
    temp = str(result)[-9:]

    if tail != temp:
        tail = temp
    else:
        flag += 1

    if flag > 10:
        break

    #print(i, str(result)[-9:], factorail(i))

if __name__ == '__main__':
    print(f"\n{str(result)[-9:]}\n\n{f' 程序用时 {time() - start_sec:.4f} 秒 ':~^45}\n")


4.2 n! 的末尾九位数字全为0


  • 当轮询到 n! 的阶乘结果后面九位数字都是 0 时,对阶乘序列总和的结果末尾九位数字就没有影响了,可以退出循环输出结果。

start_sec = time()
n = 202320232023

result = 0
for i in range(1, n + 1):
    print(' '*50, end='\r')
    print(f"{' '*(i%40)}正在计算……", end='\r') 
    temp = factorail(i)

    if str(temp)[-9:] == '0'*9:
        break

    result += temp
    #print(i, str(result)[-9:], factorail(i))

if __name__ == '__main__':
    print(f"\n{str(result)[-9:]}\n\n{f' 程序用时 {time() - start_sec:.4f} 秒 ':~^45}\n")


  此题目不是考查我等只晓得哈哈写代码的人,而是要求有很好的洞察力和分析力,可以看透事物本质的能力。实实在在循环202320232023次,是行没通滴。



回页目录

5、完整源码

(源码较长,点此跳过源码)

#!/sur/bin/nve python
# coding: utf-8
from time import time


def factorail(n):

    if n in (0, 1):
        return 1

    result = 1

    for i in range(2, n+1):
        result *= i

    return result


#if __name__ == '__main__':
    #for i in range(1, 45):
        #print(factorail(i))


#input() 

# 总和后九位数字连续十次不变
start_sec = time()
n = 202320232023

result = flag = 0
tail = None
for i in range(1, n + 1):
    print(' '*50, end='\r')
    print(f"{' '*(i%40)}正在计算……", end='\r') 
    result += factorail(i)
    temp = str(result)[-9:]

    if tail != temp:
        tail = temp
    else:
        flag += 1

    if flag > 10:
        break

    #print(i, str(result)[-9:], factorail(i))

if __name__ == '__main__':
    print(f"\n{str(result)[-9:]}\n\n{f' 程序用时 {time() - start_sec:.4f} 秒 ':~^45}\n")


input(flag) 


# n! 后九位数字全0
start_sec = time()
n = 202320232023

result = 0
for i in range(1, n + 1):
    print(' '*50, end='\r')
    print(f"{' '*(i%40)}正在计算……", end='\r') 
    temp = factorail(i)

    if str(temp)[-9:] == '0'*9:
        break

    result += temp
    #print(i, str(result)[-9:], factorail(i))

if __name__ == '__main__':
    print(f"\n{str(result)[-9:]}\n\n{f' 程序用时 {time() - start_sec:.4f} 秒 ':~^45}\n")


input(000000000) 


回页首

上一篇:  排位赛结果“测谎”(甲乙丙丁说的关于排位赛结果只正确一半,根据甲乙丙丁说的信息求出正确的排位赛结果顺序)
下一篇: 统计字符中字符出现的次数(输入一个字符串,输出字符及相应字符出现的次数)

我的HOT博:

  本次共计收集 209 篇博文笔记信息,总阅读量 32.76w,平均阅读量 1567。已生成 21 篇阅读量不小于 3000 的博文笔记索引链接。数据采集于 2023-05-02 05:31:52 完成,用时 4 分 36.44 秒。


  1. 让QQ群昵称色变的神奇代码
    ( 53588 阅读)
    博文地址:https://blog.csdn.net/m0_57158496/article/details/122566500
    点赞:23   踩 :0  收藏:77  打赏:0  评论:16
    本篇博文笔记于 2022-01-18 19:15:08 首发,最晚于 2022-01-20 07:56:47 修改。
  2. ChatGPT国内镜像站初体验:聊天、Python代码生成等
    ( 48348 阅读)
    博文地址:https://blog.csdn.net/m0_57158496/article/details/129035387
    点赞:123   踩 :0  收藏:786  打赏:0  评论:73
    本篇博文笔记于 2023-02-14 23:46:33 首发,最晚于 2023-03-22 00:03:44 修改。
  3. pandas 数据类型之 DataFrame
    ( 8019 阅读)
    博文地址:https://blog.csdn.net/m0_57158496/article/details/124525814
    点赞:6   踩 :0  收藏:24  打赏:0  评论:0
    本篇博文笔记于 2022-05-01 13:20:17 首发,最晚于 2022-05-08 08:46:13 修改。
  4. 罗马数字转换器|罗马数字生成器
    ( 6389 阅读)
    博文地址:https://blog.csdn.net/m0_57158496/article/details/122592047
    点赞:0   踩 :0  收藏:1  打赏:0  评论:0
    本篇博文笔记于 2022-01-19 23:26:42 首发,最晚于 2022-01-21 18:37:46 修改。
  5. Python字符串居中显示
    ( 6075 阅读)
    博文地址:https://blog.csdn.net/m0_57158496/article/details/122163023
    点赞:1   踩 :0  收藏:5  打赏:0  评论:1
    本篇博文笔记于 2021-12-26 23:35:29 发布。
  6. 斐波那契数列的递归实现和for实现
    ( 5292 阅读)
    博文地址:https://blog.csdn.net/m0_57158496/article/details/122355295
    点赞:4   踩 :0  收藏:2  打赏:0  评论:8
    本篇博文笔记于 2022-01-06 23:27:40 发布。
  7. 个人信息提取(字符串)
    ( 4958 阅读)
    博文地址:https://blog.csdn.net/m0_57158496/article/details/124244618
    点赞:1   踩 :0  收藏:8  打赏:0  评论:0
    本篇博文笔记于 2022-04-18 11:07:12 首发,最晚于 2022-04-20 13:17:54 修改。
  8. 练习:字符串统计(坑:f‘string‘报错)
    ( 4865 阅读)
    博文地址:https://blog.csdn.net/m0_57158496/article/details/121723096
    点赞:0   踩 :0  收藏:1  打赏:0  评论:0
    本篇博文笔记于 2021-12-04 22:54:29 发布。
  9. 练习:尼姆游戏(聪明版/傻瓜式•人机对战)
    ( 4584 阅读)
    博文地址:https://blog.csdn.net/m0_57158496/article/details/121645399
    点赞:14   踩 :0  收藏:42  打赏:0  评论:0
    本篇博文笔记于 2021-11-30 23:43:17 发布。
  10. 回车符、换行符和回车换行符
    ( 4340 阅读)
    博文地址:https://blog.csdn.net/m0_57158496/article/details/123109488
    点赞:0   踩 :0  收藏:2  打赏:0  评论:0
    本篇博文笔记于 2022-02-24 13:10:02 首发,最晚于 2022-02-25 20:07:40 修改。
  11. python清屏
    ( 4251 阅读)
    博文地址:https://blog.csdn.net/m0_57158496/article/details/120762101
    点赞:0   踩 :0  收藏:5  打赏:0  评论:0
    本篇博文笔记于 2021-10-14 13:47:21 发布。
  12. 密码强度检测器
    ( 3875 阅读)
    博文地址:https://blog.csdn.net/m0_57158496/article/details/121739694
    点赞:1   踩 :0  收藏:4  打赏:0  评论:0
    本篇博文笔记于 2021-12-06 09:08:25 首发,最晚于 2022-11-27 09:39:39 修改。
  13. 罗马数字转换器(用罗马数字构造元素的值取模实现)
    ( 3805 阅读)
    博文地址:https://blog.csdn.net/m0_57158496/article/details/122608526
    点赞:0   踩 :0  收藏:0  打赏:0  评论:0
    本篇博文笔记于 2022-01-20 19:38:12 首发,最晚于 2022-01-21 18:32:02 修改。
  14. 练习:生成100个随机正整数
    ( 3573 阅读)
    博文地址:https://blog.csdn.net/m0_57158496/article/details/122558220
    点赞:1   踩 :0  收藏:3  打赏:0  评论:0
    本篇博文笔记于 2022-01-18 13:31:36 首发,最晚于 2022-01-20 07:58:12 修改。
  15. 练习:班里有人和我同生日难吗?(概率probability、蒙特卡洛随机模拟法)
    ( 3529 阅读)
    博文地址:https://blog.csdn.net/m0_57158496/article/details/124424935
    点赞:1   踩 :0  收藏:2  打赏:0  评论:0
    本篇博文笔记于 2022-04-26 12:46:25 首发,最晚于 2022-04-27 21:22:07 修改。
  16. Python列表(list)反序(降序)的7种实现方式
    ( 3513 阅读)
    博文地址:https://blog.csdn.net/m0_57158496/article/details/128271700
    点赞:4   踩 :0  收藏:11  打赏:0  评论:8
    本篇博文笔记于 2022-12-11 23:54:15 首发,最晚于 2023-03-20 18:13:55 修改。
  17. 我的 Python.color() (Python 色彩打印控制)
    ( 3353 阅读)
    博文地址:https://blog.csdn.net/m0_57158496/article/details/123194259
    点赞:2   踩 :0  收藏:7  打赏:0  评论:0
    本篇博文笔记于 2022-02-28 22:46:21 首发,最晚于 2022-03-03 10:30:03 修改。
  18. 练习:仿真模拟福彩双色球——中500w巨奖到底有多难?跑跑代码就晓得了。
    ( 3203 阅读)
    博文地址:https://blog.csdn.net/m0_57158496/article/details/125415626
    点赞:3   踩 :0  收藏:4  打赏:0  评论:3
    本篇博文笔记于 2022-06-22 19:54:20 首发,最晚于 2022-06-23 22:41:33 修改。
  19. 聊天消息敏感词屏蔽系统(字符串替换 str.replace(str1, *) )
    ( 3065 阅读)
    博文地址:https://blog.csdn.net/m0_57158496/article/details/124539589
    点赞:3   踩 :0  收藏:2  打赏:0  评论:3
    本篇博文笔记于 2022-05-02 13:02:39 首发,最晚于 2022-05-21 06:10:42 修改。
  20. Linux 脚本文件第一行的特殊注释符(井号和感叹号组合)的含义
    ( 3031 阅读)
    博文地址:https://blog.csdn.net/m0_57158496/article/details/123087606
    点赞:0   踩 :0  收藏:4  打赏:0  评论:3
    本篇博文笔记于 2022-02-23 13:08:07 首发,最晚于 2022-04-04 23:52:38 修改。
  21. 练习:求列表(整数列表)平衡点
    ( 3014 阅读)
    博文地址:https://blog.csdn.net/m0_57158496/article/details/121737612
    点赞:0   踩 :0  收藏:0  打赏:0  评论:0
    本篇博文笔记于 2021-12-05 23:28:10 发布。
推荐条件 阅读量突破三千
(更多热博,请点击蓝色文字跳转翻阅)

回页首


老齐漫画头像

精品文章:

来源:老齐教室


回页首

Python 入门指南【Python 3.6.3】


好文力荐:


CSDN实用技巧博文:


Logo

旨在为数千万中国开发者提供一个无缝且高效的云端环境,以支持学习、使用和贡献开源项目。

更多推荐