题目所说的H-number 和H-prime 就相当于我们理解的 正常的数字和素数之间的关系一样。其实就是一种变形的求素数,以及两个素数的积。
首先要求出来H-number,之后就和正常的求素数的方法一样了,只是此时是在H-number的集合之上进行。
求出H-prime后,它们的两两乘积就是我们要求的目标,统计他们的个数就行了。
代码如下:
#include<iostream>
#include<cstdio>
#include<cstring>
#include<algorithm>
#define MAX 1000010
using namespace std;
int u[MAX],h[MAX],hpri[MAX];
int sum[MAX];
int num=1,len;
void init() //类似求素数一样,先打表
{
int i,j=1;
memset(u,1,sizeof(u));
for(i=1;i<MAX;i+=4)
{
h[j++]=i;
}
len=j-1;
for(i=2;i<=len;i++)
{
if(u[h[i]]) hpri[num++]=h[i];
for(j=1;j<num;j++)
{
if(h[i]*hpri[j]>MAX) break;
u[h[i]*hpri[j]]=0;
if(h[i]%hpri[j]==0) break;
}
}
}
void work() //H-prime 两两乘积,然后统计个数
{
int i,j;
memset(u,0,sizeof(u));
for(i=1;i<num;i++)
{
if(hpri[i]*hpri[i]>MAX)
break;
for(j=i;j<num;j++)
{
long long temp=hpri[i]*hpri[j];
if(temp<MAX)
u[temp]=1;
else break;
}
}
for(i=1;i<MAX;i++)
{
sum[i]=sum[i-1]+u[i];
}
}
int main()
{
int H;
init();
work();
while(cin>>H&&H)
{
cout<<H<<" "<<sum[H]<<endl;
}
return 0;
}