在m和n之间生成素数

时间:2014-05-22 13:38:02

标签: c++ performance algorithm

这是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)是否有更快的方法来解决这个问题?

1 个答案:

答案 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;
}