【发布时间】:2014-05-22 13:38:01
【问题描述】:
这是spoj.com上的练习题http://www.spoj.com/problems/PRIME1/..
我的提交给出了“超出时间限制”
约束是:1
我根据eratosthenes的筛子写了如下代码,
void sieve(int m,int n)
{
bool prime[1000005];
bool prime2[1000005];
int i;
int k;
prime[0]=1;
prime[1]=1;
int mi=sqrt(n);
for (int i=2; i<=mi; i++)
if (prime[i]==0)
for ( k=i*i; k<=n; k+=i)
{
if(k<=mi)
prime[k]=1;
if(k>=m)
{
prime2[k-m]=1;
}
}
int u=min(n,(int)1000000);
for(i=0;i<u;i++){
if(prime2[i]==0 && i+m>=2 && i+m<=n)
printf("%d\n",i+m);
}
printf("\n");
}
这里的“m”和“n”是我们必须生成素数的数字范围。
我面临的问题是当我将输入作为 100000000 100100000 运行需要 1.04 秒 (ideone.com C++ 4.3.2) 和 10000000 10100000 需要0.07秒
1)为什么时代差异如此之大,是什么原因造成的?
2) 有没有更快的方法来解决这个问题?
【问题讨论】:
-
不要每次都重新计算筛子,计算一次,然后对每个输入进行迭代。代码也有点乱,首先你声明 i,然后在 for 循环中隐藏它,u 检查没有多大意义,等等。 -EDIT- 等等!您是否每次都认真地从 0 迭代到最大值并检查该索引是否在范围内?
-
你真的这样缩进你的代码吗?你发在这里的时候不觉得丢脸吗?你没有想到“嗯,我在公开发布这个并要求人们免费查看它,所以也许我应该让它看起来不像撒旦的后路,更像是快乐的 C++ 代码?”
-
@user2657257:你有很多关于编程的知识——仅仅因为某些东西似乎可以工作并不意味着它没有错误。您肯定可以看到这些数组从未初始化,因此您有未定义的行为?
-
@Dukeling 好吧,Erastothenes 筛子的复杂度为
O(n log log n),你有 6 秒的时间来完成这项任务。对其进行惰性评估非常非常低效,因此通过消除过程,您只需要计算完整的筛子(并享受所述算法的相当好的缓存行为),然后对其进行迭代。 -
@user2657257 在调试模式下可以。在发布时,绝对不是。
标签: c++ performance algorithm