对于输入数字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 检查您之前的算法!