一个数,使用两次0-9这十个数字,被称为double pandigital number,那么有多少个这能被11整除的double pandigital number呢?
首先我们要明白,遍历所有的double pandigital number,然后再看看是否能整除11这种直接的暴力算法肯定是不行的,因为double pandigital number数太多了,大约是20!/(2^10)*0.9。
那怎么办呢?先考虑能被11整除的数的性质,奇位数的数字之和减去偶位数的数字之和,能被11整除。
所以,我们不需要精确的知道数字是多少,只要通过排列组合知识,把满足题意的数字的个数计算出来就好。
从20个里面选择10个数字作为奇位数上的数字,C(20, 10) = 184756,这个量级做循环操作还是能搞定的。
选出了奇位数的数字,很容易就能得到偶位数的数字。
有了这些数字我们就能通过排列组合的知识来计算个数了。
如果没有数字重复,结果是10!,每出现一个数字重复,就除以2(重复数字交换,还是同一个数字)。
这里忽略了两个问题。
一个是0开头的没有被排除,不管怎么折腾,总会有0在第一位,所以把总结果乘以0.9就好了。
第二个问题是,选择出来的奇位数可能重复,因为我们传入的参数有两个0,两个1,等等,对于组合算法来说,选择第一个0和选择第二个0是两种不同的组合,但是对于我们组成数字来说,没有区别,所以我们还需要一个集合,记住那些被计算过了的被选择出来的奇位数。
1 | public static long GetAnswer() |