题目:
The number, 1406357289, is a 0 to 9 pandigital number because it is made up of each of the digits 0 to 9 in some order, but it also has a rather interesting sub-string divisibility property.
Let d1 be the 1st digit, d2 be the 2nd digit, and so on. In this way, we note the following:
- d2d3d4=406 is divisible by 2
- d3d4d5=063 is divisible by 3
- d4d5d6=635 is divisible by 5
- d5d6d7=357 is divisible by 7
- d6d7d8=572 is divisible by 11
- d7d8d9=728 is divisible by 13
- d8d9d10=289 is divisible by 17
Find the sum of all 0 to 9 pandigital numbers with this property.
代码为:__author__ = 'Administrator'
import itertools,math,time
t=time.time()
soucestr='0123456789'
re_list=[]
totalsum=0
divlist=[2,3,5,7,11,13,17]
matched=0
for numstrlist in itertools.permutations(soucestr):
numstr=''.join(numstrlist)
matched=0
for indexnum in xrange(7,0,-1):
if not int(numstr[indexnum:indexnum+3])%divlist[indexnum-1]:
matched+=1
else:
break
if matched==7:
totalsum+=int(numstr)
#re_list.append(numstr)
"""
for numstr,templist in re_list:
print numstr,templist
"""
#print sum([int(numstr) for numstr in re_list])
print time.time()-t
运行结果为:16695334890
6.16100001335
不过运行结果太慢了,要6 秒钟。太长了。真的。
自己花了差不多一个小时改了下:
这种方法的思路是。把0-1000里能被2,3,5,7,11,14,17整除的数都列出来,然后组合出最终结果。
代码为:
import time
#coding=utf-8
starttime = time.time()
def getlist(sourcestr,numdict,index,divlist,outlist):
if index==-1:
print sourcestr
if len(sourcestr)==9:
outlist.append(sourcestr)
else:
notmatchedset=numdict[divlist[index]]
if sourcestr:
notmatchedset={numstr for numstr in notmatchedset if numstr[0] not in sourcestr and numstr[-2:]==sourcestr[0:2] }
if not notmatchedset:
return
for numstr in notmatchedset:
if index==len(divlist)-1:#如果第一次迭代
getlist(numstr+sourcestr,numdict,index-1,divlist,outlist)
else:
getlist(numstr[0]+sourcestr,numdict,index-1,divlist,outlist)
divlist=[2,3,5,7,11,13,17]
soucedict=dict()
for num in divlist:
soucedict.setdefault(num,set())
for num in range(0,1000):
numstr='{0:03d}'.format(num)
if len(str(numstr))>len(set(str(numstr))):
continue
else:
for divnum in divlist:
if not num%divnum:
soucedict[divnum].add(numstr)
count=0
outlist=[]
getlist("",soucedict,len(divlist)-1,divlist,outlist)
print sum([int(item) for item in outlist])
print time.time()-starttime
#print '{0:02d}'.format(0)
运行结果为:406357289
106357289
160357289
460357289
130952867
430952867
1695334890
0.00500011444092
生活就是一个不断发现自己是一个SB的过程。。。。。
这个题目就是一个迭代啊。很简单的东西啊我居然想了这么久。。。
牛人的代码为:
import time
#coding=utf-8
starttime = time.time()
def checkStrNum(str1):
'''str1: string of length 3 or greater'''
return not(str1[0] in str1[1:]) and str1[1] != str1[2]
pandigital = [];
for num in range(1,1000):
if num % 17 == 0:
strnum = str(num)
if len(strnum) == 2:
strnum = '0' + strnum
if checkStrNum(strnum):
pandigital.append(strnum)
divisors = [13,11,7,5,3,2,1]
for div in divisors:
auxpandigital = []
for addNum in range(0,10):
for numPan in pandigital:
newPan = str(addNum) + numPan
if checkStrNum(newPan) and int(newPan[0:3]) % div == 0:
auxpandigital.append(newPan)
pandigital = auxpandigital
total = 0
for finalPan in pandigital:
total += int(finalPan)
print(total)
print time.time()-starttime
#print '{0:02d}'.format(0)
166953348900.000999927520752