0. 题目含义: 求解 n! 包含多少个因子a

1. 主要函数:

  • void getPrime():筛法求素数的模板代码
  • int getBiggestPrimeFactor(int a):获取输入a分解的最大的质因数
  • int getFactorNum(int n, int factor):核心函数,递归求解,计算n!中包含质因子factor的数量

2. 理论依据:

任何大于2的正整数都可以写成若干质数乘积的形式。

n! 可以分解质因子乘积的形式,a也可以分解成若干质因子乘积的形式。而 n! 中包含多少个因子a,就可以转化为 n! 的质因子乘积包含多少a的质因子乘积。

而a分解出的最大质因子 biggestPrimeFactor 在 n! 质因子乘积中出现次数最少,因此 n! 包含因子a的数量就等于包含多少 biggestPrimeFactor 的数量。如果 biggestPrimeFactor 的指数 index 大于1,经过getFactorNum()求得的结果还需要除以 index 才是最终结果。

(有时间补个示意图,只有文字有点抽象。)

3. 代码:

#include <iostream>
#include <cstring>
#include <vector>
#include <cmath>

using namespace std;

const int MAXN = 1001;

vector<int> prime;
bool isPrime[MAXN];

// 筛法求素数集合
void getPrime(){
    memset(isPrime, true, sizeof(isPrime));    // 元素全部初始化为true
    isPrime[0] = false, isPrime[1] = false;
    for(int i=2; i<MAXN; i++){
        if(!isPrime[i]){    // 非质数则跳过
            continue;
        }else{
            prime.push_back(i);
            for(int j=i*i; j<MAXN; j+=i){
                isPrime[j] = false;    //质数的倍数为非质数
            }
        }
    }
}

// 获取输入a分解的最大的质因数及其指数
pair<int ,int> getBiggestPrimeFactor(int a){
    int upper_bound = sqrt(a)+1;
    pair<int ,int> biggestPrimeFactor = make_pair(1, 0);
    for(int i=0;i<a && i<upper_bound;i++){
        int factor = prime[i];
        int index = 0;
        while(a%factor==0){    // 不断试除
            a/=factor;
            index++;
        }
        if(a==1){        // a最终被完全分解,所有质因数都已经找到
            biggestPrimeFactor.first = factor;
            biggestPrimeFactor.second = index;
            break;
        }
    }
    if(a>1){    // a最终没有被完全分解,那么a原来只含这一个大于sqrt(a)的质因数,且指数必定为1
        biggestPrimeFactor.first = a;
        biggestPrimeFactor.second = 1;
    }    
    return biggestPrimeFactor;
}


//核心函数:递归求解,计算 n! 中包含质因子 factor 的数量
int getFactorNum(int n, int factor){
        return n==0? 0 : n/factor + getFactorNum(n/factor,factor);
}

int main(){
    getPrime();
    int n, a;
    cin >> n >> a;
    // 设置pair保存:最大质因数的底数和指数
    pair<int ,int> biggestPrimeFactor = getBiggestPrimeFactor(a);
    int factor = biggestPrimeFactor.first;
    int res = getFactorNum(n, factor);
    // 得到的结果要除以最大质因数的指数才是最终结果
    res /= biggestPrimeFactor.second;
    cout << res << endl;
    return 0;
}