繁体   English   中英

回文数可被任何给定数整除

[英]Palindromic numbers divisible by any given number

我要解决以下问题:数字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)

该问题显示为Euler 655项目

您得到的所有回文数在0到10**32之间,然后使用除数进行过滤。 但是您也可以采用其他方法。 只需找到小于10**3210000019倍数,然后检查每个倍数是否是回文。

这样,您可以避免检查回文中是否存在不需要的数字。

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

好吧,您只需要检查除数可整除的数字,那么为什么要在此之前检查数字,并在递增时为何不仅仅增加除数呢?

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))

这种方法仍然需要很多时间,我建议您找到一种更好的方法。

鉴于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次迭代)。

暂无
暂无

声明:本站的技术帖子网页,遵循CC BY-SA 4.0协议,如果您需要转载,请注明本站网址或者原文地址。任何问题请咨询:yoyou2525@163.com.

 
粤ICP备18138465号  © 2020-2024 STACKOOM.COM