Facebook Hacker Cup 2015 Round 1--Homework(筛选法求素数)

题意:给定A,B,K(A<=B)三个数,问在[A,B]范围内的数素数因子个数为K的个数。
题解:典型的筛选法求素数。首先建立一个保存素数因子个数的数组factorNum[],以及到n为止含有素数因子个数为k的二维数组sumNum[n][k]。
factorNum能够由筛选法确定。初始化数组为0。


1. 从小到大遍历给定最大范围内的数,若遍历到数n时,factorNum[n]=0则说明这个数是素数(前面没有它的因子)。
2. 然后通过添加n的倍数,来筛选出最大范围内含有素数因子n的数。
sumNum能够由简单的dp确定:
- 若factorNum[n] = k,则sumNum[n][k] = sumNum[n-1][k]+1。


- 对于其它k,sumNum[n][k] = sumNum[n-1][k]。

代码例如以下:

#include<cstdio>
#include<cstring>
#include<algorithm>
using namespace std;
#define maxN 10000005


short factorNum[maxN];
int sumNum[maxN][9];
short maxFactorNum;

int generateFactorNum()
{
    memset(factorNum,0,sizeof(factorNum));
    memset(sumNum,0,sizeof(sumNum));
    maxFactorNum = -1;
    for(int i = 2;i < maxN;i++)
    {
        if(factorNum[i] == 0)
        {
            factorNum[i] = 1;
            for(int k = 2;k*i < maxN;k++)
            {
                factorNum[k*i]++;
            }
        }
        memcpy(sumNum[i],sumNum[i-1],sizeof(int)*9);
        sumNum[i][factorNum[i]]++;
        maxFactorNum = max(maxFactorNum,factorNum[i]);
    }
    return 0;
}

int main()
{
    freopen("homework.txt","r",stdin);
    freopen("out1.txt","w",stdout);
    int T;
    int A,B,K;
    scanf("%d",&T);
    generateFactorNum();
    for(int i = 1;i <= T;i++)
    {
        scanf("%d%d%d",&A,&B,&K);
        printf("Case #%d: ",i);
        if(K > maxFactorNum)
        {
            printf("0\n");
        }
        else
        {
            printf("%d\n",sumNum[B][K]-sumNum[A-1][K]);
        }
    }
    return 0;
}
posted @ 2016-03-13 13:57  zfyouxi  阅读(254)  评论(0编辑  收藏  举报