我要解决以下问题: 数字545、5995和15151是可被109整除的三个最小回文。有九个小于100000的回文可被109整除。
多少个小于10 ** 32的回文可以被10000019整除?
所以我的代码如下所示。 从理论上讲,我的代码可以工作,但是从0到10 ** 32的所有数字都将实际占用我的计算机。
反正还有改进此代码的地方吗?
Python代码:
listPalindroms=[]
for i in range (0,10**32):
strI = str(i)
printTrue = 1
if len(strI) == 1:
listPalindroms.append(i)
else:
if len(strI)%2 ==0:
FinalVal = int(len(strI)/2)
for count in range (0,FinalVal):
if strI[count]!=strI[-count-1]:
printTrue = 0
if printTrue==1: listPalindroms.append(i)
else:
FinalVal = int(round(len(strI)/2))-1
for count in range (0,FinalVal):
if strI[count]!=strI[-count-1]:
printTrue = 0
if printTrue ==1: listPalindroms.append(i)
i=0
for item in listPalindroms:
if item%10000019 ==0:
i = i + 1
print (i)
问题显示为Project Euler 655
答案 0 :(得分:2)
您将得到0到10**32
之间的所有回文,然后使用除数进行过滤。但是您也可以采用其他方法。只要找到10000019
的倍数小于10**32
,然后检查每个倍数是否是回文。
这样,您可以避免检查回文中是否存在不需要的数字。
i = 1
number = 10000019
list_palindromes = []
element = number * i
while element < (10**32):
e = str(element)
for j in range(len(e)):
if e[j] != e[len(e)-j-1]:
break
if len(e)-1 == j:
list_palindromes.append(e)
print(e)
i += 1
element = number * i
答案 1 :(得分:1)
鉴于MathJax在这里不起作用,提出我的解决方案会很困难。
当您查看数字时,例如1991年,您可以将其写为1000 * 1 + 100 * 9 + 10 * 9 + 1 * 1。 如果将除以19的余数看一下,我们会得到:
(1000 * 1 + 100 * 9 + 10 * 9 + 1 * 1)%19 =((1000%19)* 1 +(100%19)* 9 +(10%19)* 9 +(1 %19)* 1)%19 =(12 * 1 + 5 * 9 + 10 * 9 + 1 * 1)%19 = 10。
因此19不会除1991
对于回文, abcba ,我们可以使用模块化算术的此属性来查看19除 abcba 时,且仅当:
(7 * a + 3 * b + 5 * c)%19 = 0
因为
(10000 * a + 1000 * b + 100 * c + 10 * b + a)%19 =(10001 * a + 1010 * b + 100 * c)%19 =(10001 * a%19 + 1010 * b%19 + 100 * c%19)%19 =(7 * a + 3 * b + 5 * c)%19
通过使用这种方法,我们可以将迭代次数减少到最大值的平方根。计算回文总和小于10 ** 10并被109整除的例程将看起来像这样。
maxValue = 10**5
divisor = 109
moduli = []
for i in range(0,33):
moduli.append((10**i)%divisor)
def test(n,div):
n = str(n)
sum_odd = 0
sum_even = 0
for i in range(len(n)):
sum_even = sum_even + int(n[i])*(moduli[i]+moduli[2*len(n)-i-1])
if i != len(n)-1:
sum_odd = sum_odd + int(n[i])*(moduli[i]+moduli[2*len(n)-i-2])
else:
sum_odd = sum_odd + int(n[i])*(moduli[i])
if sum_odd%div==0 and sum_even%div==0:
return 2
if sum_odd%div==0 or sum_even%div==0:
return 1
else:
return 0
# The sum starts at -1 because 0 is counted twice
sum = -1
for a in range(maxValue):
sum = sum + test(a,divisor)
print(sum)
为每个小于10 ** 32的回文运行计算,仍然需要进行10 ** 16次迭代,因此对于您的问题而言效率不高,但是它比以前的答案要好(需要10 ** 24次迭代)。 / p>
答案 2 :(得分:0)
那么,您只需要检查除数可整除的数字,那么为什么要在此之前检查数字,并在递增时为何不增加除数呢?
def is_palin(num):
num_str = str(num)
for index in range(len(num_str)/2):
if num_str[index]==num_str[len(num_str)-1-index]:
continue
return False
return True
def multiple(divisor, end):
count=0
index = divisor*2
while index<end:
if is_palin(index):
count+=1
index+=divisor
return count
if __name__=="__main__":
print(multiple(109, 100000))
# print(multiple(10000019, 10**32))
这种方法仍然需要很多时间,我建议您找到一种更好的方法。