筛选法 || POJ 3292 Semi-prime H-numbers

5,9,13,……叫H-prime
一个数能且仅能由两个H-prime相乘得到,则为H-semi-prime
问1-n中的H-semi-prime有多少个
*解法:vis初始化为0代表H-prime,vis[i]=0&&vis[j]==0则i*j是H-semi-prime,标记为1,否则i与j中至少有一个能由两个H-prime相乘得到,那么i*j就可由多个H-prime相乘得到,标记为-1
#include <iostream>
#include <cstdio>
#include <cstring>
using namespace std;
#define SZ 1000005
int hp[SZ], num[SZ];
int vis[SZ];
void Hprime(int n)
{
    memset(num, 0, sizeof(num));
    memset(vis, 0, sizeof(vis));
    for(int i = 5; i <= n; i += 4)
    {
        for(int j = 5; j <= i; j += 4)
        {
            if(i * j > SZ) break;//当乘积大于最大值时就可以break
            if(vis[i] == 0 && vis[j] == 0) vis[i * j] = 1;
            else vis[i * j] = -1;
        }
    }
    for(int i = 5; i <= n; i++)
    {
        num[i] = num[i - 1];
        if(vis[i] == 1) num[i]++;
    }
    return;
}
int main()
{
    int n;
    Hprime(SZ);
    while(1)
    {
        scanf("%d", &n);
        if(n == 0) break;
        printf("%d %d
", n, num[n]);
    }
    return 0;
}
原文地址:https://www.cnblogs.com/pinkglightning/p/8372740.html