PE32-Pandigital products

题目:https://projecteuler.net/problem=32

题意:求所有满足如下条件的数z的和:z能分解成两个数x、y的积,且x、y、z中的digits刚好是1~9各出现一次

分析:1~9的permutation总共也就362880,对其枚举即可,这里有一个重要的剪枝:x末位 * y末位 % 10如果不等于z的末位,则继续下一次枚举,实测发现加上这一剪枝比不加的情况快1倍多

from itertools import permutations as Permute

def unite(arr):
	n = 0
	for x in arr:
		n = n * 10 + x
	return n


seq = range(1, 10)
tot = 0
his = set()

for arr in Permute(seq, 9):
	# enumerate lhs length, no more than 4
	for i in range(1, 5):
		# enumerate rhs length, no more than lhs
		for j in range(1, i+1):
			k = 9 - i - j
			# the product should has length no less than i and j
			if k < i or k < j:
				break
			# so arr[:i] is lhs, arr[i:i+j] is rhs, arr[i+j:] is product
			if arr[i-1] * arr[i+j-1] % 10 != arr[-1]:
				# last digit do not match, so cut it off
				continue

			z = unite(arr[i+j:])
			if z in his:
				continue
			x = unite(arr[:i])
			y = unite(arr[i:i+j])
			if x * y == z:
				print('%d * %d = %d' % (x, y, z))
				tot += z
				his.add(z)
print(tot)

  • 0
    点赞
  • 0
    收藏
    觉得还不错? 一键收藏
  • 0
    评论
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值