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



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

已经发布了有点太长的评论,所以将其更改为回答:

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

截至目前,您正在执行N*N次传递,每次计算x和y的数字总和(还不错),并分解每个总和以检查它是否是素数(非常糟糕)。这意味着s您正在检查它是否是黄金s+1时间!(对于 0+s, 1+(s-1), ..., (s-1)+1, s+0)。

您可以采取哪些不同措施?

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

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

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

  • 数字在第一次和第 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)。这意味着我们的 sodo 和 sody 是 <= 9*lenN,所以素数p = sodx + sody <= 18*lenN

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

最新更新