题目描述
来源
OpenJudge网站 —— 百练习题集-第2731号习题
要求
总时间限制: 5000ms 内存限制: 655360kB
描述
求10000以内n的阶乘。
输入
只有一行输入,整数n(0<=n<=10000)。
输出
一行,即n!的值。
样例输入
100
样例输出
93326215443944152681699238856266700490715968264381621468592963895217599993229915608941463976156518286253697920827223758251185210916864000000000000000000000000
来源
JP06
解题思路
-
这一题的难点是:n很大时,n!的结果会大到无法用一个整数变量来存储。解决办法是用一个列表(即数组)来存储作为结果的整数的各个数位。
-
下面一节给出的代码中,用n_digits列表存储作为结果的整数的各个数位。n_digits[0]是个位,[1]是十位,[2]是百位, …,依次类推。
-
假设n_digits存储了(m-1)!的结果,那么如何求m!呢?答案是,n_digits的各个数位分别乘以m。具体做法是:
(1)令jinwei = 0。jinwei变量记住向前的进位。
(2)个位乘以m。n_digits[0] = n_digits[0] * m + jinwei。进位jinwei = n_digits[0]除以10的商;新的个位n_digits[0] = n_digits[0]除以10的余数。
(3)十位乘以m,加上进位jinwei。n_digits[1] = n_digits[1] * m + jinwei。进位jinwei = n_digits[1]除以10的商;新的个位n_digits[1] = n_digits[1]除以10的余数。
(4)百位乘以m,加上进位jinwei。n_digits[2] = n_digits[2] * m + jinwei。进位jinwei = n_digits[2]除以10的商;新的个位n_digits[2] = n_digits[2]除以10的余数。
(5)…
(6)依次类推,一直到(m-1)!的最高位。把最高位的进位记作jinwei。
(7)如果jinwei > 0,那么增设一位最高位,其值 = jinwei % 10。令jinwei = jinwei 除以10的商。
(8)如果jinwei > 0,那么增设一位最高位,其值 = jinwei % 10。令jinwei = jinwei 除以10的商。
(9)…
(10)重复上一步骤,直至jinwei等于0。
参考答案
# print("10!=", 10*9*8*7*6*5*4*3*2*1)
# print("15!=", 15*14*13*12*11*10*9*8*7*6*5*4*3*2*1)
from array import array
n_digits = array('L') #n_digits[0]是个位,[1]是十位,[2]是百位, ...
#n_digits存储了(m-1)!的结果,求出m!的结果
def times(n_digits, m):
#各个数位乘以m
jinwei = 0
for i in range(len(n_digits)):
n_digits[i] = n_digits[i] * m + jinwei
jinwei = n_digits[i] // 10
n_digits[i] = n_digits[i] % 10
#最高位的进位目前可能是数十,数百,数千,...
while jinwei > 0:
n_digits.append(jinwei % 10)
jinwei = jinwei // 10
return n_digits
n = int(input())
if n <= 1:
print(1)
else:
n_digits.append(1) #1! = 1
for i in range(2, n+1):
n_digits = times(n_digits, i)
for d in n_digits[len(n_digits)-1::-1]:
print(d, end='')
print()
测试用例
-
题目描述给出的测试用例,结果值比较大。要比对样例输出和程序输出,可以把两组数据复制到同一个编辑器窗口内,上下对齐,比对就容易了。
-
小一点的n。
样例输入
10
样例输出
3628800 -
另一个小一点的n。
样例输入
15
样例输出
1307674368000
你应该能够猜到上一节代码中的前两行的作用了。 -
n=1。
样例输入
1
样例输出
1
小结
- 把“参考答案”一节的代码提交到OpenJudge网站上后,反馈的结果是“ Time Limit Exceeded ”,意思是超时,用时超过了50000ms(即50秒)。采用同样的算法,用C语言实现的代码提交到OpenJudge网站上后,返回的结果是“Accepted”,用时2373ms。可见:(1)算法没有问题。(2)Python的运行效率比较低。
- 有人把类似问题概括为高精度整数类型的问题。这一类问题通常会生成一个巨大的数,大到无法用变量直接存储的数。