問題一:
給定整數n,求n以內有多少個素數
分析:
應用篩選法,其核心思想就是,首先將2~n范圍內的所有整數寫出來。其中最小的數字2是素數,將表中所有2的倍數都划去。表中剩余的最小的數字是3,它不能被更小的整數除,所以它是素數,再將表中所有的3得倍數都划去。以此類推,如果表中剩余的數字是m的話,m就是素數,然后再將所有的m的倍數划去。
#include<iostream>
#include<stdio.h>
using namespace std;
int prime[1000009];///保存素數
bool is_prime[1000009];///表示i是不是素數
int sieve(int n)
{
int ans=0;
for(int i=0;i<=n;i++)
is_prime[i]=true;
is_prime[0]=is_prime[1]=false;
for(int i=2;i<=n;i++)
{
if(is_prime[i])
{
prime[ans++]=i;
for(int j=2*i;j<=n;j+=i)
is_prime[j]=false;
}
}
return ans;
}
int main()
{
int n;
scanf("%d",&n);
printf("%d\n",sieve(n));
return 0;
}
問題二:
求一個特定的區間 (a<=x<b) 內的素數的個數
#include<iostream>
#include<stdio.h>
typedef long long ll;
using namespace std;
bool is_prime_small[1000009];
bool is_prime[1000009];
///對區間[a,b)內的整數進行篩選。 is_prime[i-a]=true <=> i是素數
void segment_sieve(ll a,ll b)
{
for(int i=0;(ll)i*i<b;i++)
is_prime_small[i]=true;
for(int i=0;i<b-a;i++)
is_prime[i]=true;
for(int i=2;(ll)i*i<b;i++)
if(is_prime_small[i])
{
for(int j=2*i;(ll)j*j<b;j+=i)
is_prime_small[j]=false;
for(ll j=max(2LL,(a+i-1)/i)*i;j<b;j+=i)
is_prime[j-a]=false;
}
}
int main()
{
ll a,b,c;
scanf("%lld%lld",&a,&b);
segment_sieve( a, b);
int ans=0;
c=b-a;
for(int i=0;i<c;i++)
{
if(is_prime[i]) ans++;//cout<<i+a<<" ";
}
if(a==1) ans--;
printf("%d",ans);
return 0;
}