该题新定义了一种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; }