032. 全数字乘积(pandigital products)

如果一个\(n\)位数的各位数恰好包含了从\(1\)\(n\)的所有数字各一次,我们就可以说这个数字是一个全数字,比如五位数15234是一个从1至5的全数字。

乘积7524是独特的,因为\(39\times186=7254\),将乘数、被乘数和乘积结合起来刚好构成一个从1至9的全数字。求所有乘数、被乘数和乘积可以构成从1至9的全数字的乘积的和。

提示:有些满足条件的乘积可以通过多种方式产生,确保它们在计算总和时只被包含了一次。

分析:这道题相对比较容易,解题的核心在于缩小搜寻乘数和被乘数的范围。经过简单的分析只有当乘数是一位或两位数,对应被乘数是四位或三位数时,乘积是四位数,从而三者加起来共有九位数。由于乘法满足交换律,我们要避免进行重复核对,假设的所求的乘数和被乘数为\(i\)\(j\)\(i<j\),则\(i\)的筛选范围是\([1,99]\)。如果\(i\)是一位数,则\(j\)的范围是\([1234,10^4/i)\);如果\(i\)是两位数,则\(j\)的范围是\([123,10^4/i)\)

确定筛选范围后,我们将乘数、被乘数和乘积转化为字条串并拼接在一起,如果形成的字符串长度为9且包含从一至九的所有数字,则该乘积满足条件,从而添加到所求结果的集合中,避免出现重复的乘积结果,最后对集体加总即为所求。

def main():
    res = set()
    for i in range(1,100):
        start = 1234 if i <=9 else 123
        for j in range(start,10000//i):
            s = str(i) + str(j) + str(i*j)
            if len(s) == 9 and set(s) == set('123456789'):
                res.add(i*j)
    return sum(res)