这是spoj.com上的一个练习题http://www.spoj.com/problems/PRIME1/ ..
我的提交内容超出时间限制"
约束是:1&lt; = m&lt; = n&lt; = 1000000000,n-m <= 100000 最多10个测试用例的时间限制:6秒
我根据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");
}
这里&#39; m&#39;和&#39; N&#39;是我们必须生成素数的数字范围。
我面临的问题是当我接受输入时 100000000 100100000运行需要1.04秒(ideone.com C ++ 4.3.2)和 10000000 10100000需要0.07秒
1)为什么时间的巨大差异,有什么贡献呢?
2)是否有更快的方法来解决这个问题?
答案 0 :(得分:2)
1)为什么时代的巨大差异,有什么贡献 这个 ?
时间的差异即将到来,因为构建筛子所需的时间对于两个范围都是不同的。对于更大的数字,它会更高。
2)是否有更快的方法来解决这个问题?
如评论中所述,您正在计算每个测试用例的筛子。您只需要构建一次筛网,最多只需要sqrt(1000000000)= 100000。
我的解决方案(很久以前)如下:
#include <iostream>
#include <algorithm>
#include <vector>
#include <cmath>
#include <iterator>
bool is_prime (const int& n, std::vector<int>& v);
int main() {
int t;
std::cin >> t;
std::vector<int> prime_array;
// build the sieve
for (int i=2; i<=100000; i++)
if ( is_prime( i, prime_array ) )
prime_array.push_back( i );
while (t--) {
long long m;
long long n;
std::cin >> m;
std::cin >> n;
if (m<2) m = 2;
//check for the prime numbers in the range.
for (int i=m; i<=n; i++)
if ( is_prime( i, prime_array ) )
std::cout << i << std::endl;
std::cout << std::endl;
}
return 0;
}
// we need to check for prime factors up to sqrt(n)
bool is_prime (const int& n, std::vector<int>& v) {
double root = sqrt (n);
std::vector<int>::iterator it = v.begin();
while ( it != v.end() && *it <= root ) {
if (!( n % *it)) return 0;
it++;
}
return 1;
}