我正在尝试解决这个编程谜题,虽然下面的代码可以正确工作,但对于成功提交来说太慢了。
- 有什么指针可以使它运行得更快(从列表中删除每个第n个元素)?
- 或者有计算相同内容的更好算法的建议;似乎我现在只能想到暴力算法……
基本上,手头的任务是:
给定: L = [2,3,4,5,6,7,8,9,10,11,........] 1. 在列表L中取第一个剩余项(在一般情况下为'n')。将其移动到“幸运数字列表”中。然后从列表中删除每个'n-th'项。 2. 重复步骤1
任务: 计算“幸运数字列表”的第n个数字(1 ≤ n ≤ 3000)
我的原始代码(它在我的机器上大约计算了3000个幸运数字需要1秒钟 - 不幸的是太慢了):
"""
SPOJ Problem Set (classical) 1798. Assistance Required
URL: http://www.spoj.pl/problems/ASSIST/
"""
sieve = range(3, 33900, 2)
luckynumbers = [2]
while True:
wanted_n = input()
if wanted_n == 0:
break
while len(luckynumbers) < wanted_n:
item = sieve[0]
luckynumbers.append(item)
items_to_delete = set(sieve[::item])
sieve = filter(lambda x: x not in items_to_delete, sieve)
print luckynumbers[wanted_n-1]
编辑:在Mark Dickinson、Steve Jessop和gnibbler的出色贡献下,我得到了以下代码,它比我的原始代码快得多(并成功地在http://www.spoj.pl提交,并且只用了0.58秒!)...
sieve = range(3, 33810, 2)
luckynumbers = [2]
while len(luckynumbers) < 3000:
if len(sieve) < sieve[0]:
luckynumbers.extend(sieve)
break
luckynumbers.append(sieve[0])
del sieve[::sieve[0]]
while True:
wanted_n = input()
if wanted_n == 0:
break
else:
print luckynumbers[wanted_n-1]