hoj题双重筛法
2012-02-29 22:19
423 查看
题意:
给出一个区间,长度<=1000 000;求其中素数相邻素数之间的差最小的和最大的;
分析:
双重筛法,其中区间的数可能较大,因此如果用试除法的话,显然不行的;
用筛选法,首先第一次筛选出从1到47000之间的素数;第二次筛选时,利用第一次筛
选出来的素数,判断L到U区间范围内的数是否是素数;
因为范围是1<=L< U<=2,147,483,647,而U-L<=1000 000;所以我们可以设置一个1000000
以内的数组,用res[i-L]的值为0或者1来表示是否是素数;
核心算法是第二次的筛选,其中j=begin*prime[i]表示的是在A,B区间中prime[i]的
第一个倍数;依次筛选;
一重筛法的程序如下:
memset(prime,false,sizeof(prime));
tot = 0;
for(int i=2;i<X;i++)
{
if(!prime[i])
isprime[tot++]=i;
for(int j=i+i;j<X;j=j+i)
prime[j] = true;
}
二重筛法的程序如下:
memset(res,false,sizeof(res));
if(m==1)
m=2;
for(int i=0;i<tot&&isprime[i]*isprime[i]<=n;i++)
{
long long temp = (m/isprime[i])+(m%isprime[i]>0);
if(temp==1)
temp = 2;
for(long long j=temp*isprime[i];j<=n;j+=isprime[i])
res[j-m]=true;
}
#include <iostream>
#include <cstring>
#include <cmath>
using namespace std;
#define X 50000
int tot;
bool prime[50000];
int isprime[10000];
bool res[1000010];
void make_prime()
{
memset(prime,false,sizeof(prime));
tot = 0;
for(int i=2;i<X;i++)
{
if(!prime[i])
isprime[tot++]=i;
for(int j=i+i;j<X;j=j+i)
prime[j] = true;
}
}
int main()
{
freopen("sum.in","r",stdin);
freopen("sum.out","w",stdout);
make_prime();
long long n,m;
while(cin>>m>>n)
{
memset(res,false,sizeof(res));
int cnt = 0;
if(m==1)
m=2;
for(int i=0;i<tot&&isprime[i]*isprime[i]<=n;i++)
{
long long temp = (m/isprime[i])+(m%isprime[i]>0);
if(temp==1)
temp = 2;
for(long long j=temp*isprime[i];j<=n;j+=isprime[i])
res[j-m]=true;
}
for(int i=0;i<=n-m;i++)
if(!res[i])
cnt++;
cout<<cnt<<endl;
}
return 0;
}
给出一个区间,长度<=1000 000;求其中素数相邻素数之间的差最小的和最大的;
分析:
双重筛法,其中区间的数可能较大,因此如果用试除法的话,显然不行的;
用筛选法,首先第一次筛选出从1到47000之间的素数;第二次筛选时,利用第一次筛
选出来的素数,判断L到U区间范围内的数是否是素数;
因为范围是1<=L< U<=2,147,483,647,而U-L<=1000 000;所以我们可以设置一个1000000
以内的数组,用res[i-L]的值为0或者1来表示是否是素数;
核心算法是第二次的筛选,其中j=begin*prime[i]表示的是在A,B区间中prime[i]的
第一个倍数;依次筛选;
一重筛法的程序如下:
memset(prime,false,sizeof(prime));
tot = 0;
for(int i=2;i<X;i++)
{
if(!prime[i])
isprime[tot++]=i;
for(int j=i+i;j<X;j=j+i)
prime[j] = true;
}
二重筛法的程序如下:
memset(res,false,sizeof(res));
if(m==1)
m=2;
for(int i=0;i<tot&&isprime[i]*isprime[i]<=n;i++)
{
long long temp = (m/isprime[i])+(m%isprime[i]>0);
if(temp==1)
temp = 2;
for(long long j=temp*isprime[i];j<=n;j+=isprime[i])
res[j-m]=true;
}
#include <iostream>
#include <cstring>
#include <cmath>
using namespace std;
#define X 50000
int tot;
bool prime[50000];
int isprime[10000];
bool res[1000010];
void make_prime()
{
memset(prime,false,sizeof(prime));
tot = 0;
for(int i=2;i<X;i++)
{
if(!prime[i])
isprime[tot++]=i;
for(int j=i+i;j<X;j=j+i)
prime[j] = true;
}
}
int main()
{
freopen("sum.in","r",stdin);
freopen("sum.out","w",stdout);
make_prime();
long long n,m;
while(cin>>m>>n)
{
memset(res,false,sizeof(res));
int cnt = 0;
if(m==1)
m=2;
for(int i=0;i<tot&&isprime[i]*isprime[i]<=n;i++)
{
long long temp = (m/isprime[i])+(m%isprime[i]>0);
if(temp==1)
temp = 2;
for(long long j=temp*isprime[i];j<=n;j+=isprime[i])
res[j-m]=true;
}
for(int i=0;i<=n-m;i++)
if(!res[i])
cnt++;
cout<<cnt<<endl;
}
return 0;
}
相关文章推荐
- 使用筛法找素数 HOJ 2098 分拆素数和
- 我的双重人格
- Mssql双重锁死的解决办法
- 为何双重检测成例在java中不成立
- hoj 11170 Weird Numbers
- 嵌套实现双重循环
- hoj 1070 图的m可着色优化问题
- Linux与Windows XP双重启动
- HOJ 1056
- C 语言二维数组和双重指针
- Windows 与Linux 的双重启动
- 数据中心双重供电解决方案5步走(1)
- java 双重检查锁定及单例模式
- 双重命名空间,出现问题
- 位数组实现用筛法(Sieve of Eratosthnes)计算素数
- HOJ 12058 Judges' Time Calculation 解题报告
- 安全专家:Twitter安全性落后 应采用双重认证
- 为什么链表初始化时,要用双重指针?
- hoj1440 Knight Moves
- HOJ——2086 Fibonacci Convolution