我的代码在我的机器上运行得非常好,但是当它被spoj编译时它给出了M + NZEC erro。 这是我的问题的链接: http://www.spoj.com/problems/CPRIME/
这是我的代码:
def smallPrimes(n):
"""Given an integer n, compute a list of the primes <= n"""
if n <= 1:
return []
sieve = range(3, n+1, 2)
top = len(sieve)
for si in sieve:
if si:
bottom = (si*si - 3)//2
if bottom >= top:
break
sieve[bottom::si] = [0] * -((bottom-top)//si)
return [2]+filter(None, sieve)
from math import *
import sys
def main():
flag=True
while(flag==True):
x=input()
if(x==0):
flag=False
return 0
z=x/log(x)
v=len(smallPrimes(x))
print round((abs(v-z)*100/(v)),1)
if __name__ == "__main__":
main()
答案 0 :(得分:2)
在SPOJ中,当Python脚本执行中发生异常时,会引发NZEC错误。 在你的情况下,因为输入中的问题被明确指定并且终止于零,所以不能因为考虑输入而考虑到这一点。
错误很可能是因为使用了比允许的内存更多的内存。在您的问题中,内存限制指定为256 MB。但是在你的代码中
sieve = range(3, n+1, 2)
此行声明一个大小约为n / 2的列表。当,n = 10 ^ 8时,这意味着你将声明一个具有5 * 10 ^ 7整数的列表,这些整数具有天真的近似值并忽略所有开销
(5*10^7)*4 bytes
~ 200 MB
包括第二个大清单声明的开销和其他内存使用情况
[0] * -((bottom-top)//si)
可以达到大约130 MB,忽略所有开销,你将超出内存限制,只是在列表中存储那么多整数。我的机器上的代码注意到大约1 GB的内存使用量。所以你的代码超过了SPOJ的内存限制,它引发了异常。
最好的办法是优化您的方法,在这些问题中很少需要声明10 ^ 8的顺序列表。我可以看到一种方式,你不需要声明一个大的列表,但由于这是一个在线评判的问题,最好让你弄清楚这种方法。 :)