如何优化和查找大型输入的输出?

时间:2019-07-18 12:23:57

标签: python primes modulo sum-of-digits

对于输入数字N,我试图找到特殊对(x,y)的数量计数,以便满足以下条件:

  • x != y
  • 1 <= N <= 10^50
  • 0 <= x <= N
  • 0 <= y <= N
  • F(x) + F(y)是质数,其中F是数字的所有数字之和

最终打印以1000000007为模的计数的输出


示例输入: 2

示例输出: 2

说明:

  
      
  • (0,2)由于F(0)+F(2)=2是素数
  •   
  • (1,2)由于F(1)+F(2)=3是素数
  •   
  • (2,1)不被视为(1,2)与(2,1)相同
  •   

我的代码是:

def mod(x,y,p):
    res=1
    x=x%p
    while(y>0):
        if((y&1)==1):
            res=(res*x)%p
        y=y>>1
        x=(x*x)%p
    return res

def sod(x):
    a=str(x)
    res=0
    for i in range(len(a)):
        res+=int(a[i])
    return res

def prime(x):
    p=0
    if(x==1 or x==0):
        return False
    if(x==2):
        return True
    else:
        for i in range(2,(x//2)+1):
            if(x%i==0):
                p+=1
        if(p==0):
            return (True)
        else:
            return(False)

n=int(input())
res=[]
for i in range (n+1):
    for j in range(i,n+1):
        if(prime(sod(int(i))+sod(int(j)))):
            if([i,j]!=[j,i]):
                if([j,i] not in res):
                    res.append([i,j])
count=len(res)
a=mod(count,1,(10**9)+7)
print(res)
print(a)

我希望9997260736的输出为671653298,但错误是代码执行超时。

1 个答案:

答案 0 :(得分:0)

已经发布了太长的评论,因此将其更改为答案:

在考虑此类问题时,不要将问题直接转换为代码,而是要看看只能做什么一次或以不同的顺序做什么。

截至目前,您正在执行N*N遍,每次计算x和y的数字总和(还不错),并分解每个和以检查其是否为质数(真的很差)。这意味着对于总和s,您要检查它是否是素数s+1倍! (适用于0 + s,1 +(s-1),...,(s-1)+ 1,s + 0)。

您可以做些什么?

让我们看看我们知道什么:

  • 许多数字的总和是相同的。

  • sod(x)和sod(y)的总和对于许多值来说都是相同的。

  • 数字在第1次和第n次检查时都是质数(并检查它的质数是否昂贵)。

因此,最好的方法是只计算一次质数,每个和仅计算一次。但是当我们有很多数字时该怎么办?

改变思维方向:获取素数,将其分为两个数(sodx和sody),然后从这些数生成x和y。

示例:

素数p = 7。这样得出的总和可能是0 + 7、1 + 6、2 + 5、3 + 4。

然后,您可以为每个和产生一个数字,例如对于N = 101和sod = 1,您有1,10,100,对于sod = 2,您有2,11,20,101。您可以存储它,但是生成它应该不会那么糟。

其他优化

您必须考虑如何使用N来限制生成质数:

给定具有lenN个数字的N(请记住,lenN是〜log(N)),最大的数字总和是9 * lenN(对于仅包含9的N)。这意味着我们的sodx和sody为<= 9 * lenN,因此素数p = sodx + sody <= 18*lenN

看:这意味着18 * lenN检查数字是否为质数,而N * N检查您先前的算法是否具有!!