Python 可被任意给定数整除的回文数

Python 可被任意给定数整除的回文数,python,Python,我有以下问题需要解决: 数字545、5995和15151是可被109整除的三个最小回文。有九个回文小于100000,可以被109整除 有多少小于10**32的回文可以被1000019整除 我的代码如下所示。 理论上,我的代码可以工作,但从0到10**32一直计算,我的计算机实际上需要数年时间 是否有改进此代码的方法 Python代码: listPalindroms=[] for i in range (0,10**32): strI = str(i) printTrue = 1

我有以下问题需要解决: 数字545、5995和15151是可被109整除的三个最小回文。有九个回文小于100000,可以被109整除

有多少小于10**32的回文可以被1000019整除

我的代码如下所示。 理论上,我的代码可以工作,但从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)

问题表现为

您将获得0到
10**32之间的所有回文,然后使用整除性进行过滤。但你也可以用另一种方式来做。只需找到
1000019
中小于
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
i=1
数字=10000019
列表_回文=[]
元素=数量*i
当元素<(10**32)时:
e=str(元素)
对于范围内的j(len(e)):
如果e[j]!=e[len(e)-j-1]:
打破
如果len(e)-1==j:
列表_回文。附加(e)
打印(e)
i+=1
元素=数量*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))
def是_palin(num):
num_str=str(num)
对于范围内的索引(len(num_str)/2):
如果num_str[index]==num_str[len(num_str)-1-index]:
持续
返回错误
返回真值
def倍数(除数,结束):
计数=0
索引=除数*2

由于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次迭代)要好。

提示:对于num范围(10000019,10**3210000019),您不需要所有介于0和10**32之间的数字:
。。。检查回文性。这仍然是一个巨大的数字范围来检查。由于您的问题是一个问题,请查找有关它的DiskUsion页面,例如,以找到更多最佳解决方案