该题新定义了一种H数,还有几个概念,要搞清楚:
1.H素数:本身不是1,不能写成两个不是1的H数才乘积。
2.H半素数:能写成2个H素数乘积的H数(注意,还得是H数)
这样我们就可以利用筛选法的思想,通过类似筛法求素数的方法筛出所有H素数。
细节参见代码:
#include<bits/stdc++.h>
using namespace std;
typedef long long ll;
const int INF = 1000000000;
const int maxn = 1000000+1;
int n,m,v,cnt=0,cur = 0,vis[maxn+5]={0},prime[maxn+5],a[maxn+5]={0};
void init() {
cnt = 0;
for(int i=1;(i*4+1)*(i*4+1)<=maxn;i++) if(!vis[i]) //类似筛法求素数
for(int j=i;(i*4+1)*(j*4+1)<=maxn;j++)
vis[4*i*j+i+j] = 1; //意思就是4*(4*i*j+i+j)+1是H素数,暗含了它还是H数
for(int i=1;i*4+1<=maxn;i++) {
if(!vis[i]) prime[cnt++] = i*4+1;//保存H素数
}
for(int i=0;i<cnt;i++) {
if(prime[i]*prime[i]>maxn) break;//计算H半素数
for(int j=i;j<cnt;j++) {
if(prime[i]*prime[j]>maxn) break;
a[prime[i]*prime[j]] = 1;
}
}
for(int i=1;i<=maxn;i++) a[i] += a[i-1];//打表记录答案
}
int main() {
init();
while(~scanf("%d",&n)&&n) {
printf("%d %d\n",n,a[n]);
}
return 0;
}