【发布时间】:2018-12-09 22:34:39
【问题描述】:
2 天以来,我一直在努力解决 SPOJ 的 PRIME1 问题。我设法编写了一个适用于大数字的程序,但我不明白为什么它会在开始范围(通常是 1-11)中显示如此混乱的数字。我正在使用 Eratosthenes 的分段筛。 SPOJ link
问题来了:
输入
输入以单行中的测试用例数量 t (t
输出
对于每个测试用例打印所有质数 p 使得 m
还有我的代码:
#include <bits/stdc++.h>
using namespace std;
#define MAX 1000000000
#define MAX_SQRT sqrt(MAX)
vector<bool> is_prime(MAX_SQRT, true);
void simpleSieve(int limit, vector<int>& primes)
{
for(int p=2; p*p<=limit; p++) {
if(is_prime[p] == true) {
for(int i=p*p; i<=limit; i+=p)
is_prime[i] = false;
}
}
for(int i=2; i<=limit; i++) {
if(is_prime[i]) primes.push_back(i);
}
}
void segmentedSieve(int left, int right)
{
int range = floor(sqrt(right)) + 1;
vector<int> primes;
simpleSieve(range, primes);
int n = right - left + 1;
bool sieve[n];
memset(sieve, true, sizeof(sieve));
for (int i = 0; i<primes.size(); i++) {
int low = floor(left/primes[i]) * primes[i];
if(low < left)
low += primes[i];
for(int a=low; a<=right; a+=primes[i]) {
sieve[a - left] = false;
}
}
for(int i=left; i<=right; i++)
if(sieve[i - left]) cout << i << "\n";
}
int main()
{
int t;
cin >> t;
while(t--) {
int left, right;
cin >> left >> right;
segmentedSieve(left, right);
}
return 0;
}
我尝试对开头部分进行硬编码,但它会因输入而异。
【问题讨论】:
-
bool sieve[n]不是有效的C++。这是一个Variable Length Array (VLA),它只是一些编译器的扩展。我看到你已经在使用std::vector。您还应该将它用于sieve。 -
我之前一直在使用它,但是由于一些实现问题我将
std::vector替换为bool数组。虽然现在使用矢量它可以正常工作,所以我已经改变了它。谢谢! -
第一次调用 simpleSieve 基本上完成了这项工作。可能问题出在
range的计算上。
标签: c++ c++11 primes sieve-of-eratosthenes