9/21/2008

为什么我的算法超时,而那个算法比我慢还能accepted ?

学习python,写算法熟悉熟悉语法,发现一个问题,百思不得其解.....

题目:
来源:http://www.proj.pl
Problem code: PRIME1

Peter wants to generate some prime numbers for his cryptosystem. Help him! Your task is to generate all prime numbers between two given numbers!

Input
The input begins with the number t of test cases in a single line (t<=10). In each of the next t lines there are two numbers m and n (1 <= m <= n <= 1000000000, n-m<=100000) separated by a space.

Output
For every test case print all prime numbers p such that m <= p <= n, one number per line, test cases separated by an empty line.

Example
Input:
2
1 10
3 5

Output:
2
3
5
7

3
5

我的算法:
[coolcode lang="python" linenum="off"]
import math
import time
def main():
data = int( raw_input())
a=[None]*data
#start1=time.time()
#print time.time()-start1
for i in xrange(data):
string=raw_input()
a[i]=string
start=time.time()
result=filter(lambda x: (x % 2 != 0 ), [x for x in xrange(3, 31623)])
buf1=[]
for x in result:
loop1=int(math.sqrt(x))+1
for m in xrange(3,loop1,2):
if (x%m)==0:
break
else:
buf1.append(x)
final=str()
for k in xrange(data):
num=a[k].split()
num1=int(num[0])
num2=int(num[1])
if num1 <= 2:
s = range(3, num2+1, 2)
elif num1 % 2 == 0:
s = range(num1+1, num2+1, 2)
else:
s = range(num1, num2, 2)
#s=filter(lambda x: (x % 2 != 0 and x % 5 != 0 and x % 3 != 0 and x % 7 != 0), [x for x in xrange(num1, num2)])
len_primes =len(buf1)
len_s=len(s)
i=0
nroot=int(num2**0.5)
while (i < len_primes and buf1[i] <= nroot+1):
p = buf1[i]
for j, d in enumerate(s):
if s[j]:
if d == p:
s[j+p::p] = [0] * (((len_s-1) - (j+p)) // p + 1)
break
elif d % p == 0:
s[j::p] = [0] * (((len_s-1) - j) // p + 1)
break
i += 1
if num1 <= 2:
result=[2] + filter(None, s)
for i in xrange(len(result)):
final+=str(result[i])+"\n"
else:
result= filter(None, s)
for i in xrange(len(result)):
final+=str(result[i])+"\n"
final+="\n"
print final
print time.time()-start
main()
[/coolcode]
测试数据:1
1000000000 1000100000
所用时间:19.8299999237
包括打印时间了.

再看看别人accepted的算法:
[coolcode lang="python" linenum="off"]
import math
import sys
import time

N = 1000000000
LIMIT = int(math.sqrt(N))

# Return list of all odd primes <= limit.
def gen_primes(limit):
# Index i represents 2i+3.
odds = range(3, limit + 1, 2)
n = len(odds)
for prime in odds:
if prime:
psq = prime ** 2
starti = (psq - 3) >> 1
if starti >= n:
break
# starti + j*prime <= n-1
# j <= (n-1-starti)/prime
j = (n - 1 - starti) // prime
odds[starti : starti + j * prime + 1 : prime] = [0] * (j+1)
return filter(None, odds)

PRIMES = gen_primes(LIMIT)

# Return list of all primes p s.t. lo <= p <= hi.
def primes_in_range(lo, hi):
if lo > hi:
return []
include2 = lo <= 2 <= hi
lo = max(lo, 3) | 1
if hi & 1 == 0:
hi -= 1
if lo > hi:
return include2 and [2] or []
# Index i represents 2i+lo.
odds = range(lo, hi+1, 2)
n = len(odds)
for prime in PRIMES:
if 3 * prime > hi:
break
# Find first odd multiple >= lo.
# i * prime >= lo
# i >= lo/prime
i = max(lo // prime, 3) | 1
first = i * prime
while first < lo:
first += 2 * prime
if first > hi:
continue
starti = (first - lo) >> 1
# starti + j*prime <= n-1
# j <= (n-1-starti)/prime
j = (n - 1 - starti) // prime
odds[starti : starti + j * prime + 1 : prime] = [0] * (j+1)
odds = filter(None, odds)
if include2:
odds.insert(0, 2)
return odds

def main():
n = int(sys.stdin.readline())
for i in xrange(1, n+1):
lo, hi = map(int, sys.stdin.readline().split())
start=time.time()
for p in primes_in_range(lo, hi):
print p
if i < n:
print
print time.time()-start
main()
[/coolcode]
测试数据:
1
1000000000 1000100000
所用时间:
22.861000061 s

Oh, who can tell me where's the problem ? Be puzzled !
python的速度慢的可怜!

2 评论:

匿名,  2008年9月21日 14:23  

你可以在linux平台上测试一下……

匿名,  2008年11月13日 06:22  

YdV7v1 kqgxqjjxnwgr, [url=http://xyavopzaowio.com/]xyavopzaowio[/url], [link=http://nworbcixbtpw.com/]nworbcixbtpw[/link], http://yxtipaznzcei.com/

发表评论