NYOJ509-因子和阶乘

题目大意:

题目链接:戳这里

给你一个正整数n,把n!=1x2x3x.....xn分解成素因子相乘的形式,并从小到大输出每个素因子的指数,但要保证最后输出的素因子个数不为0。例如 5的阶乘是120 =2 x 2 x 2 x 3 x 5   所以输出  3 1 1 .。

n组测试数据;   n(0<n<10000)    接下来n行每行有一个整数 m(1<m<10000)

解题思路:

比如  12 的阶乘  是12 x 11 x 10 x 9 x 8 x 7 x 6 x 5 x 4 x 3 x 2 x 1

拿3来举例子   12里面包含了因子3  9里面也包含了3  还有 6   还有3  一共是4个   12/3=4  

由此可见 【m/因子】向下取整就是m的阶乘中包含这个因子的次数  但是这样还没有统计完

比如 9=3x3  里面含有因子3两次  但是我们只统计了一次  所以  再加上    12/(3*3)

当然 还有 3*3*3 ....所以  我们对1-m中所有的素数 i   累加   m/i   m/(i*i)   m/(i*i*i)........直到(i*i*i.....>m)

AC代码及注释

#include<stdio.h>
#include<string.h>
using namespace std;
const int maxn=1e4+7;
bool isprime[maxn];
int cnt[maxn];
int T,n,ans;
void table(){//筛素数表
    for(int i=0;i<=maxn;i++)isprime[i]=true;
    isprime[0]=isprime[1]=false;
    for(int i=2;i<=maxn;i++){
        if(isprime[i]){
            for(int j=i*2;j<=maxn;j+=i)isprime[j]=false;
        }
    }
}
int main(){
    table();
    scanf("%d",&T);
    while(T--){
        scanf("%d",&n);ans=0;
        memset(cnt,0,sizeof(cnt));//计数
        for(int i=2;i<=n;i++){
            if(isprime[i]){
                int f=i;
                while(f<=n){//统计次数
                    cnt[i]+=n/f;
                    f=f*i;
                }
                if(i>ans)ans=i;//记录最大的素因子
            }
        }
        for(int i=2;i<=ans;i++){
            if(isprime[i])printf("%d ",cnt[i]);
        }
        printf("\n");
    }
    return 0;
}

猜你喜欢

转载自blog.csdn.net/holly_Z_P_F/article/details/82078941