先用类似筛素数的方法,筛出primeH_number。然后所有primeH_number两两相乘所得的数即为semi-primeH_number了。
#include <iostream>
#include <cstdio>
#include <cstring>
using namespace std;
#define M 1000010
int vis[M];
int prime[M],p;
int cnt[M];
void init()
{
memset(vis,0,sizeof(vis));
p=0;
for(int i=1;4*i+1<=1000001;i++) if(!vis[4*i+1])
{
prime[p++]=4*i+1;
for(int j=1;4*j+1<=1000001;j++)
if((long long)(4*j+1)*(4*i+1)>1000001) break;
else vis[(4*i+1)*(4*j+1)]=1;
}
for(int i=0;i<p;i++)
for(int j=i;j<p;j++)
if((long long)prime[j]*prime[i]>1000001) break;
else vis[prime[j]*prime[i]]=2;
memset(cnt,0,sizeof(cnt));
for(int i=1;i<=1000001;i++)
if(vis[i]==2) cnt[i]=cnt[i-1]+1;
else cnt[i]=cnt[i-1];
}
int main()
{
freopen("in.txt","r",stdin);
int n;
init();
while(cin>>n&&n)
{
cout<<n<<" "<<cnt[n]<<endl;
}
return 0;
}