【问题标题】:How to optimize and find output for large inputs?如何优化和查找大输入的输出?
【发布时间】:2019-11-27 09:10:58
【问题描述】:

对于输入数字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,但错误是代码执行超时。

【问题讨论】:

  • 最好为 [something] 以下的所有素数生成可能的总和,然后对该数字总和进行数字化,而不是遍历所有数字并分解每个总和以检查其是否为素数。
  • 我的意思是:到目前为止,您正在执行 N*N 次传递,每次计算 x 和 y 的数字总和(还不错)并分解每个总和以检查它是否鼎盛时期。这意味着对于 sum s,您正在检查它是否是素数 s+1 次! (对于 0+s, 1+(s-1), ..., (s-1)+1, s+0)
  • 您可以做的是:从 2 开始遍历素数(您将只检查每个素数一次)。,求和(对于 7: 0+7, 1+6 , 2+5, 3+4),并且对于总和的两个元素生成它们可能的 x 和 y 值(例如,给定“1”和 N=101,您可以做 1、10、100;给定“2”,您会得到2、11、20、101……)。
  • @rossum 那是!=,不是x!... 这意味着“不相等”
  • @Guy [0,12] = 3 因为 F(0)+F(12)=0+3=3 这是素数(数字 12 的数字总和为 3)对于其他集合类似

标签: python primes modulo sum-of-digits


【解决方案1】:

已经发了有点太长的cmets,所以换个回答:

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

到目前为止,您正在执行N*N 传递,每次计算 x 和 y 的数字总和(没那么糟糕)并分解每个总和以检查它是否是素数(真的很糟糕)。这意味着对于 sum 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 来限制生成素数:

给定 N 和 lenN 个数字(请记住,lenN 是 ~log(N)),可能的最大数字总和是 9*lenN(对于仅由 9 组成的 N)。这意味着我们的 sodx 和 sody 是 p = sodx + sody <= 18*lenN

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

【讨论】:

    猜你喜欢
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 2023-03-24
    • 2019-03-11
    • 2021-07-23
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    相关资源
    最近更新 更多