http://acm.sdut.edu.cn/sdutoj/problem.php?action=showproblem&problemid=2404
题目没什么好说的,也不难理解,就是超时问题一直没解决,写了三种方法,前两种是7s左右,最后一种4s。
第一种
1 #!/usr/bin/python 2 #coding=utf-8 3 import math 4 max = 100000 5 prime = [1]*max 6 def isprime(): 7 for m in xrange(0,2): 8 prime[m] = 0 9 for j in xrange(3,max): 10 if j%2 == 0: 11 prime[j] = 0 12 else: 13 prime[j] = 1 14 xn = int(math.sqrt(max*1.0)) 15 for k in xrange(3,xn+1): 16 if prime[k]: 17 for l in xrange(2*k,max,k): 18 prime[l] = 0 19 r = 1 20 s = [1]*max 21 isprime() 22 for f in xrange(2,max): 23 if prime[f] == 1: 24 s[r]=f 25 r=r+1 26 n = input() 27 for v in xrange(1,n+1): 28 flag = 0 29 o=1 30 a=input() 31 if prime[a] == 0: 32 print "Case %d: no"%v 33 continue 34 while s[o]<=a/2+1: 35 p=o 36 tmp=a 37 while tmp>0: 38 tmp = tmp -s[p] 39 p=p+1 40 o=o+1 41 if tmp == 0: 42 flag=1 43 break 44 if flag: 45 print "Case %d: yes"%v 46 else: 47 print "Case %d: no"%v
第二种
首先用dic存储n范围内的元素,然后依次标记,最后从头扫描一次dic,把合适的元素放在list中返回结果,据说这样求素数比直接用列表存要快,我测试了一下一千万的数据大概跑7s。
1 #!/usr/bin/python 2 #coding=utf-8 3 def prime(n): 4 lis = {} 5 for i in xrange(2,n+1): 6 if not i in lis: 7 lis[i] = 1 8 k = i*2 9 while k<=n: 10 lis[k] = 0 11 k = k+i 12 ans = [] 13 for i in lis: 14 if lis[i] == 1: 15 ans.append(i) 16 return ans 17 pr = prime(100000) 18 n = input() 19 for j in xrange(0,n): 20 flag = 0 21 o=0 22 a=input() 23 if not a in pr: 24 print "Case %d: no"%j 25 continue 26 while pr[o]<=a/2+1: 27 p=o 28 tmp=a 29 while tmp>0: 30 tmp = tmp-pr[p] 31 p+=1 32 o+=1 33 if tmp == 0: 34 flag=1 35 break 36 if flag: 37 print "Case %d: yes"%j 38 else: 39 print "Case %d: no"%j
第三种
这个主要是改进了下面的判断,跑到4s,不过还是超时,希望能找到更好的解法。
1 #!/usr/bin/python 2 #coding=utf-8 3 def prime(n): 4 lis = {} 5 for i in xrange(2,n+1): 6 if not i in lis: 7 lis[i] = 1 8 k = i*2 9 while k<=n: 10 lis[k] = 0 11 k = k+i 12 ans = [] 13 for i in lis: 14 if lis[i] == 1: 15 ans.append(i) 16 return ans 17 pr = [] 18 pr = prime(1000001) 19 n = input() 20 cntnum = 0 21 while n: 22 n=n-1 23 cnt = 0 24 issuper=False 25 j=0 26 lower=0 27 sum=0 28 a = input() 29 if a in pr: 30 while True: 31 if sum < a: 32 if sum+pr[j] > a: 33 sum-=pr[lower] 34 lower+=1 35 else: 36 sum+=pr[j] 37 j+=1 38 if lower > j: 39 break 40 elif sum==a: 41 if pr[j]!=pr[lower+1]: 42 issuper = True 43 break 44 if issuper: 45 cntnum+=1 46 print "Case %d: yes"%cntnum 47 else: 48 cntnum+=1 49 print "Case %d: no"%cntnum 50 else: 51 cntnum+=1 52 print "Case %d: no"%cntnum