1. 程式人生 > >【POJ 3292】 Semi-prime H-numbers

【POJ 3292】 Semi-prime H-numbers

遍歷 ems const art cstring times article blank %d

【POJ 3292】 Semi-prime H-numbers


打個表

題意是1 5 9 13...這樣的4的n次方+1定義為H-numbers

H-numbers中僅僅由1*自己這一種方式組成 即沒有其它因子的 叫做H-prime

兩個H-prime的乘積叫做H-semi-prime 另一個要求是H-semi-prime僅僅能由兩個H-prime組成 即4個H-number 不可由3個或幾個H-number構成

篩出來個滿足題意的表 把每一個數內滿足的個數存起來O(1)輸出就可以


代碼例如以下:


#include <iostream>
#include <cstdio>
#include <cstring>

using namespace std;
const int sz = 1000001;

int IsPrim[sz+1];
int p[sz];
int tp;

void Init()
{
    memset(IsPrim,0,sizeof(IsPrim));//H-numbers都初始化0 即默認都為H-prime
    int i,j,cnt;
    tp = 1;
    for(i = 5; i <= sz; i += 4)
    {
        for(j = 5; j*i <= sz; j += 4)
        {
            if(IsPrim[i] || IsPrim[j])//兩個數有一個不是H-prime 組合就不為H-semi-prime
                IsPrim[i*j] = -1;
            else IsPrim[i*j] = 1;//否則組合為H-semi-prime 註意 H-semi-prime就不為H-prime了 因為順序枚舉 後面遍歷到的之前肯定會推斷一下 故不會漏判
        }
    }
    cnt = 0;
    for(i = 1; i <= 1000001; ++i)
    {
        if(IsPrim[i] == 1) cnt++;

        p[tp++] = cnt;
    }
}


int main()
{
    Init();
    int h;
    while(~scanf("%d",&h) && h)
    {
        h = (h-1)/4*4+1;
        printf("%d %d\n",h,p[h]);
    }
    return 0;
}


【POJ 3292】 Semi-prime H-numbers