对于输入数字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)的总和相同。
Number在第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检查您以前的算法是否具有!