http://poj.org/problem?id=3292

H-number 是4*n + 1 (n >= 1) 而 H-prime h 则是只包含因子 1和h的H-number 这里特别注意h是也要是H-number 所以9在这里就是素数了。才开始自己以为从4*n + 1这批数中选出素数然后枚举所有的乘积,然后记录个数。样例肯定不会过了。

思路一样可就是素数筛选时,要选H-prime

pku 3292 Semi-prime H-numbers 数论素数筛选的变形_学习pku 3292 Semi-prime H-numbers 数论素数筛选的变形_ios_02View Code
#include <iostream>
#include <cstdio>
#include <cstring>
#include <algorithm>
#define maxn 1000007
using namespace std;

int p[maxn],dp[maxn],f[maxn];
int len;
void init()
{
    int i,j;
    long long tmp;
    memset(f,0,sizeof(f));
    //关键是这里的筛选
    for (i = 1; (4*i + 1) < maxn; ++i)
    {
        int num = 4*i + 1;
        if (!f[num])
        {
           for (j = num*2; j < maxn; j += num) f[j] = 1;
        }
    }
    len = 0;
    for (i = 1; (4*i + 1) < maxn; ++i)
    {
        int num = 4*i + 1;
        if (!f[num]) p[len++] = num;
    }
    memset(dp,0,sizeof(dp));
    for (i = 0; i < len; ++i)
    {
        for (j = i; j < len; ++j)
        {
            tmp = (long long)p[i]*p[j];
            if (tmp <= 1000001) dp[tmp] = 1;
            else break;
        }
    }
    for (i = 1; i < maxn; ++i)
    {
        dp[i] = dp[i - 1] + dp[i];
    }
}

int main()
{
    int n;
    init();
    while (~scanf("%d",&n))
    {
        if (!n) break;
       printf("%d %d\n",n,dp[n]);
    }
    return 0;
}