求指定区间的质数-python版 【Sphere OJ】

        很多大家常用的OJ平台都只提供C,C++,Java等常用语言,但还是有很多OJ提供其他语言支持,Sphere OJ 应该算里面最出名的之一。Sphere里面第二题求质数的问题,我觉得非常有意思,因为我提交了好几个版本都是“time limit exceeded ”,于是我想把代码放出来,供感兴趣的人一起讨论讨论,抛砖引玉~~

        题目链接http://www.spoj.com/problems/PRIME1/ 题目如下:

2. Prime Generator

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
Warning: large Input/Output data, be careful with certain languages (though most should be OK if the algorithm is well designed)


        下面开始我的解法:求质数,最开始想到的就是试除法,然后2的倍数不用试,直接剔除;再然后选试除的范围,比如求[a,b]这个闭区间内的质数,最大的试除的数应该是sqrt(b)。于是假设参数 j 遍历[a,b]这个闭区间的元素,每个 j 对应要试除的元素为[2 ,3 ,4 ,5 ,6 ,... min( j , sqrt(b) ) ] ;再再然后,我可以在遍历[a,b]闭区间的时候把2的倍数无视掉,于是每个 j 对应要试除的元素为[2 ,3 ,5 ,7 ,9 ,... min( j , sqrt(b) ) ] 。按此思路我的代码如下:

import math
def check(n,elem):
	for e in elem:
		if n%e==0:
			return False
	return True

def primeNumber(a,b):
	if b<2:
		return
	elif b==2:
		print(2)
		return
	total=[]
	if a<=2:
		a=3
		total.append(2)
		print(2)
	elif a%2==0:
		a+=1
	mid=int(math.sqrt(b))
	for j in range(a,b+1,2):
		elem=list(range(3,min(j,mid+1),2))
		if check(j,elem):
			total.append(j)
			print(j)

num=input()
num=int(num)
for i in range(num):
	data=input()
	a,b=data.split(' ')
	a=int(a)
	b=int(b)
	primeNumber(a,b)

        这样还是超时,于是我到网上搜,才得知有个“筛法”。于是用筛法重写,思路一样,还是先无视掉2的倍数,然后依次把从3到sqrt(b) 之间的数做为基,把列表中这些基的倍数全删掉,剩下的为输出。代码如下:

import math
def primeNumber(a,b):
	if b<2:
		return
	elif b==2:
		print(2)
		return
	mid=int(math.sqrt(b))
	s=list(range(3,b+1,2))
	n=3
	for i in range(3,mid+1,2):
		while True:
			tmp=i*n
			if tmp >b:
				break
			elif tmp in s:
				s.remove(tmp)
			n+=2
	if a<=2:
		print(2)
	for x in s:
		if x>=a:
			print(x)

x=int(input())
for i in range(x):
	data=input()
	a,b=data.split()
	a=int(a)
	b=int(b)
	primeNumber(a,b)

        采用了筛法还是超时。我看了下这个OJ用的主机数据:

  • Pyramid (Intel Pentium III 733 MHz) - consists of old solid Pentium III machines that serve SPOJ since its very beginning in 2004. Thanks to the fact that these machines are slow, judges created by SPOJ problem setters can more easily test the complexity of the algorithms used in your solution without creating enormous datasets (we can even tell the difference between O(n) and O(nlogn) if needed). On this cluster memory limit for submissions is 256 MB.

        不知道是不是733M的主频所致。。。好了,抛砖引玉,希望大家给出更好的方法~~:-)


转载请注明:转自 http://blog.csdn.net/littlethunder/article/details/9287013

你可能感兴趣的:(算法,python,ACM,质数,OJ)