货物摆放
小蓝有一个超大的仓库,可以摆放很多货物。
现在,小蓝有 n n n 箱货物要摆放在仓库,每箱货物都是规则的正方体。小蓝规定了长、宽、高三个互相垂直的方向,每箱货物的边都必须严格平行于长、宽、高。
小蓝希望所有的货物最终摆成一个大的长方体。即在长、宽、高的方向上分别堆 L L L、 W W W、 H H H 的货物,满足 n = L × W × H n = L \times W \times H n=L×W×H。
给定 n n n,请问有多少种堆放货物的方案满足要求。
例如,当 n = 4 n = 4 n=4 时,有以下 6 6 6 种方案: 1 × 1 × 4 、 1 × 2 × 2 、 1 × 4 × 1 、 2 × 1 × 2 、 2 × 2 × 1 、 4 × 1 × 1 1×1×4、1×2×2、1×4×1、2×1×2、2 × 2 × 1、4 × 1 × 1 1×1×4、1×2×2、1×4×1、2×1×2、2×2×1、4×1×1
请问,当 n = 2021041820210418 n = 2021041820210418 n=2021041820210418 (注意有 16 16 16 位数字)时,总共有多少种方案?
思路
- 因为是填空题,所以直接暴力
- 数据很大,所以用 p y t h o n python python 暴力
- 题目可以转化为:求将一个数 n n n 分解成三个因数相乘的方法数,并且不同顺序也算不同方法数
- 解题思路可以为:把数 n n n 的所有因数求出来(包括1和本身),相同的因数取一次,再遍历这些因数,求出每个因数分解的因数个数,累加即可
- 比如题目所给的4:
- 首先分解因数,得到序列 ( 1 , 2 , 4 ) (1,2,4) (1,2,4)
- 再遍历,首先是1:易知 1 = 1 × 1 1=1\times1 1=1×1,只有一种分法
- 然后是2: 2 = 1 × 2 , 2 = 2 × 1 2=1\times2,2=2\times1 2=1×2,2=2×1,共两种分法,注意不同顺序算不同的分法
- 然后是4: 4 = 1 × 4 , 4 = 2 × 2 , 4 = 4 × 1 4=1\times4,4=2\times2,4=4\times1 4=1×4,4=2×2,4=4×1,共三种分法
- 综上可知:方法数为 1 + 2 + 3 = 6 1+2+3=6 1+2+3=6种,也可验证,这种思路是正确的
代码如下
# 首先可以用计算器算出根号2021041820210418的值,向上取整为44955999
# 然后计算其所有因数
ans = [] # 用于存因数
num = 2021041820210418
for i in range(1, 44955999):
if(num % i == 0):
ans.append(i)
ans.reverse()
res = []
for i in ans:
res.append(num//i)
ans.reverse()
ans.extend(res)
print(ans)
然后得到以下结果:
[1, 2, 3, 6, 9, 17, 18, 27, 34, 51, 54, 102, 131, 153, 262, 306, 393, 459, 786, 918, 1179, 2227, 2358, 2857, 3537, 4454, 5714, 6681, 7074, 8571, 13362, 17142, 20043, 25713, 40086, 48569, 51426, 60129, 77139, 97138, 120258, 145707, 154278, 291414, 374267, 437121, 748534, 874242, 1122801, 1311363, 2245602, 2622726, 3368403, 5882353, 6362539, 6736806, 10105209, 11764706, 12725078, 17647059, 19087617, 20210418, 35294118, 38175234, 52941177, 57262851, 100000001, 105882354, 114525702, 158823531, 171788553, 200000002, 300000003, 317647062, 343577106, 600000006, 770588243, 900000009, 1541176486, 1800000018, 2311764729, 2700000027, 4623529458, 5400000054,6935294187, 13100000131, 13870588374, 16805882521, 20805882561, 26200000262, 33611765042, 39300000393, 41611765122, 50417647563, 78600000786, 100835295126, 117900001179, 151252942689, 235800002358, 285700002857, 302505885378, 353700003537, 453758828067, 571400005714, 707400007074, 857100008571, 907517656134, 1714200017142, 2201570610251, 2571300025713, 4403141220502, 5142600051426, 6604711830753, 7713900077139, 13209423661506, 15427800154278, 19814135492259, 37426700374267, 39628270984518, 59442406476777, 74853400748534, 112280101122801, 118884812953554, 224560202245602, 336840303368403, 673680606736806, 1010520910105209, 2021041820210418]
再写一个求解程序即可,因为是暴力,所以就没有在意复杂度了
import math
def check(n):
'''
判断一个数是不是平方数
'''
k = int(math.sqrt(n))
if(k*k == n):
return True
return False
def cal_num(n):
'''
计算一个数的因数个数
'''
t = 0
for i in range(1, int(math.sqrt(n))+1):
if(n % i == 0):
t += 2
if(check(n)):
# 如果是平方数的话,要少算一个才行
t -= 1
return t
# 借用上一个程序的结果
ans = [1, 2, 3, 6, 9, 17, 18, 27, 34, 51, 54, 102, 131, 153, 262, 306, 393, 459, 786, 918, 1179, 2227, 2358, 2857, 3537, 4454, 5714, 6681, 7074, 8571, 13362, 17142, 20043, 25713, 40086, 48569, 51426, 60129, 77139, 97138, 120258, 145707, 154278, 291414, 374267, 437121, 748534, 874242, 1122801, 1311363, 2245602, 2622726, 3368403, 5882353, 6362539, 6736806, 10105209, 11764706, 12725078, 17647059, 19087617, 20210418, 35294118, 38175234, 52941177, 57262851, 100000001, 105882354, 114525702, 158823531, 171788553, 200000002, 300000003, 317647062, 343577106, 600000006, 770588243, 900000009, 1541176486, 1800000018, 2311764729, 2700000027, 4623529458, 5400000054,6935294187, 13100000131, 13870588374, 16805882521, 20805882561, 26200000262, 33611765042, 39300000393, 41611765122, 50417647563, 78600000786, 100835295126, 117900001179, 151252942689, 235800002358, 285700002857, 302505885378, 353700003537, 453758828067, 571400005714, 707400007074, 857100008571, 907517656134, 1714200017142, 2201570610251, 2571300025713, 4403141220502, 5142600051426, 6604711830753, 7713900077139, 13209423661506, 15427800154278, 19814135492259, 37426700374267, 39628270984518, 59442406476777, 74853400748534, 112280101122801, 118884812953554, 224560202245602, 336840303368403, 673680606736806, 1010520910105209, 2021041820210418]
cnt = 0 # 方法数
for i in ans:
cnt += cal_num(i)
print(cnt)