0090 立方体数对
* * * *
拉格朗日计划
* * * *
立方体数对

考虑两个立方体,每个立方体的六个面上标有六个不同的0至9之间的数字。将这两个立方体并排摆放,我们就可以得到一系列两位数。

例如,平方数64可以通过这样摆放获得:



通过合理选择两个立方体上的数字,我们可以摆放出所有小于100的平方数:01、04、09、16、25、36、49、64、81。

例如,可以在一个立方体上标上0、5、6、7、8、9,在另一个立方体上标上1、2、3、4、8、9。

在本题中,我们允许将标有6或9的面颠倒过来使用,也就是6和9都既可以作为6,也可以作为9使用,如此则0、5、6、7、8、9和1、2、3、4、6、7这样的标法也能表示所有小于100的平方数(若不允许颠倒则无法表示09)。

在这一规则(允许6和9相互替代)下,有多少种不同的标记两个立方体的方法,使之可以摆放出小于100的所有九个平方数?

注意:尽管能表示的数相同,但将一个立方体标记为1、2、3、4、5、6和将其标记为1、2、3、4、5、9应视作两种不同标记方法。

注意:两个立方体之间无区别,即在甲立方体标记0、5、6、7、8、9,在乙立方体标记1、2、3、4、8、9,和在甲立方体标记1、2、3、4、8、9,在乙立方体标记0、5、6、7、8、9视作是同一种标记方法。

本题难度:



解答

从10个数字中选出6个,选两次再相互组合,总共只有$\binom{10}{6}^2\cdot 6^2\cdot 2$约三百万种可能,因此暴力搜索即得结果$1217$。

import itertools

d=[0,1,2,3,4,5,6,7,8,9]
t=0
q={6:9,19:16,39:36,46:49,94:64}

for a in itertools.combinations(d,6):
    for b in itertools.combinations(d,6):
        p=dict.fromkeys([1,4,9,16,25,36,49,64,81],1)
        for i in a:
            for j in b:
                k=q.get(i*10+j,i*10+j) 
                if k in p:
                    p[k]=0
                k=q.get(j*10+i,j*10+i) 
                if k in p:
                    p[k]=0
        if sum(p[k] for k in p)==0:
            t+=1

print t/2