蓝桥杯:阶乘约数

news/2025/1/16 2:55:20/

蓝桥杯:阶乘约数icon-default.png?t=N2N8https://www.lanqiao.cn/problems/1020/learning/

目录

题目描述

        填空题:答案是 39001250856960000

题目分析

AC代码(Java)

暴力

线性筛


题目描述

        填空题

        定义阶乘 n!=1×2×3×⋅⋅⋅×n。

        请问 100! (100 的阶乘)有多少个正约数。

题目分析

        这道题考数论。

        这道题需要用到唯一分解定理:任何一个大于1的自然数 N,如果N不为质数,那么N可以唯一分解成有限个质数乘积

        在这里插入图片描述

       上述式子中,N为大于1的自然数,P1为质数,a^{1}为P1这个质数使用的次数。

        计算N的约数的话就是(1+a_{1})*(1+a_{2})*(1+a_{3})*....*(1+a_{n}

        如180,可以唯一分解成: 2*2*3*3*5,写成定理的样子:2^{2}*3^{2}5^{1},那么他的约数个数就是(1+2)*(1+2)*(1+1) = 3*3*2 = 18个约数。

        在换成题目来说,我们求一下5!他有多少个约数。

        120 可以分解成 120 /2 = 60 ,60 /2 = 30 , 30/2 = 15 , 15/3 = 5 

        所以它可以表示成120=2*2*2*3*5,也就是2^{3}*3^{1}*5^{1},所以它的约数为:(1+3)*(1+1)*(1+1) = 16个约数。

        但是我们要计算的是100!(100的阶乘),不可能直接先把100!的具体值算出来在计算。

        所以我们根据5!来看,看看能不能拆分一下

        5!是 2*3*4*5, 那么,2可以表示成2^{1},3可以表示成3^{1},4可以表示成2^{2},5可以表示成5^{1}

        将他们组合一下,不就是变成了 2^{1}*3^{1}*2^{2}*5^{1}

        合并一下,就是 2^{3}*3^{1}*5^{1}

        然后根据定理找约数:(1+3)*(1+1)*(1+1) = 16。跟直接将120进行分解的结果一致。

        所以我们可以得到,5!只需要分别对2,3,4,5每个数进行唯一分解,得出使用的质数的数量(如2一共使用了3次,所以就是2^{3},最后继续合并,然后计算即可。

        知道了规律之后,就可以直接从1-100循环,每次将当前的i分解,将其分解出来的每个质数记录下来,令其使用次数+1。

        循环结束之后,就遍历我们记录质数使用次数的数组,然后根据质数的使用次数,如2这个质数使用了10次,那么就让 答案 乘上 (1+10)即可。

        因为我们将100!拆成了1-100之间每个数的质数组成,所以暴力也很快,绝对不会超过1s

        假设我们每次遍历,都需要将1-100之间的质数判断一下,那么撑死也就是100*100,也就是10^{4},1s出答案绰绰有余了。

        我分别写一个一个 普通遍历(暴力找质数) 线性筛模板 的方法。仅供参考。

AC代码(Java)

        需要注意的是,答案会很大,Java要用BigInteger,C的话开long long.

暴力

import java.math.BigInteger;// 1:无需package
// 2: 类名必须Main, 不可修改public class Main {//唯一分解定理:任何一个正整数都可以分解成若干个质数的乘积//暴力求public static void main(String[] args) {//Java会爆long,要用大数BigInteger ans = new BigInteger("1");//记录每个质数出现的次数,只统计1-100的int[] target = new int[101];for(int i = 1;i<=100;i++) {int x = i;//把x拆成若干个质因数相乘,for (int j = 2; j <=x; j ++) {//如果j不为质数,就跳过if(!check(j)) continue;while(x % j == 0) {target[j] ++;x /= j;}}//如果循环结束了,那么需要查看x是否为1//为1则代表是任意一个质数的0次方,对应的值为(1+0),1乘进结果中结果不变,所以不用管//如果不为1代表还剩有质数没有处理,直接记录即可if(x > 1) target[x]++;}//统计完了1-100的所有质因数出现,我们就计算结果//根据唯一定理公式,每个质数的出现次数+1就是这个正整数中对应的计算 (1+array[j])for(int i = 2;i<=100;i++) {//i这个数没有出现过,不需要计算,直接跳过if(target[i] == 0) continue;//Java的大数运算很麻烦,需要创建相同的对象进行操作,还需要接受操作结果BigInteger x = new BigInteger(""+(1+target[i]));ans = ans.multiply(x);}System.out.println(ans.toString());}//判断是否为质数public static boolean check(int x) {for(int i = 2;i<=Math.sqrt(x);i++) {if(x % i == 0) return false;}return true;}
}

线性筛

        线性筛的话挺有趣的,有兴趣可以去了解一下,没兴趣的也可也背一下模板,比赛可能会用到。

import java.math.BigInteger;// 1:无需package
// 2: 类名必须Main, 不可修改public class Main {//唯一分解定理:任何一个大于1的自然数N都可以分解成若干个质数的乘积//来一波线性筛把1-100的质数筛出来,直接暴力求也可以,我就当练习模板了static int N = 110;static int[] primes = new int[N];static boolean[] st = new boolean[N];public static void initPrimes(){int index = 0;for(int i = 2;i<N;i++) {if(!st[i]) primes[++index] = i;for(int j = 1;primes[j]*i<N;j++) {st[primes[j]*i] = true;if(primes[j] % i == 0) break;}}}public static void main(String[] args) {initPrimes();//Java会爆long,要用大数BigInteger ans = new BigInteger("1");//记录每个质数出现的次数,只统计1-100的int[] target = new int[101];for(int i = 1;i<=100;i++) {int x = i;//把x拆成若干个质因数相乘,for(int j = 1;j<x;j++) {while(x%primes[j] == 0){//primes[j]就是一个质数target[ primes[j] ]++;x /= primes[j];}}//如果循环结束了,那么需要查看x是否为1//为1则代表是任意一个质数的0次方,对应的值为(1+0),1乘进结果中结果不变,所以不用管//如果不为1代表还剩有因数没有处理if(x > 1) target[x]++;}//统计完了1-100的所有质因数出现,我们就计算结果//根据唯一定理公式,每个质数的出现次数+1就是这个正整数中对应的计算 (1+array[j])for(int i = 1;i<=100;i++) {//i这个数没有出现过,不需要计算,直接跳过if(target[i] == 0) continue;//Java的大数运算很麻烦,需要创建相同的对象进行操作,还需要接受操作结果BigInteger x = new BigInteger(""+(1+target[i]));ans = ans.multiply(x);}System.out.println(ans.toString());}
}

        

 

 

 


http://www.ppmy.cn/news/37880.html

相关文章

vue3+ts+vite+electron搭建桌面应用

提示&#xff1a;文章写完后&#xff0c;目录可以自动生成&#xff0c;如何生成可参考右边的帮助文档 vue3tsviteelectron搭建桌面应用前言一、版本背景介绍二、过程1. 搭建vitevue-ts的项目2. 接入electron3. electron启动4. electron打包5. 项目目录梳理前言 提示&#xff1…

腾讯后端开发实习一面(24届)

毫无准备的腾讯一面&#xff0c;最近都在忙比赛去了&#xff0c;突然收到腾讯一面的邮件&#xff0c;直接没准备。。。 总结&#xff0c;除了Vue其他的都挺好&#xff0c;但是腾讯hr为啥Vue面我四个问题&#xff0c;不是面的后端开发吗&#xff0c;好难呀&#xff0c;都只能随…

Spring AOP:理解动态代理和 Advice

ProxyFactory cglib代理解析 jdk动态代理 动态代理技术在Spring中进行了封装,封装出来的类叫做ProxyFactory,表示是创建一个代理对象的一个工厂,比jdk动态代理和cglib代理更加方便,比如: public class UserService {public void test(){System.out.println("test...&qu…

2023年 合肥市庐阳区信息学竞赛区赛 小学组

2023年 合肥市庐阳区信息学竞赛区赛 小学组T1.快递盒(box) 问题描述 快递盒底面长为 a、宽为 b,货品包装的底面为正方形,边长为 c。快递盒同货品包装的高度一致,货品包装边要求同快递盒边平行。请问快递盒最多可以装入多少件货品? 输入格式 一行,三个整数 a、b 和 c,意…

Golang每日一练(leetDay0022)

目录 64. 最小路径和 Minimum Path Sum &#x1f31f;&#x1f31f; 65. 有效数字 Valid Number &#x1f31f;&#x1f31f;&#x1f31f; 66. 加一 Plus One &#x1f31f; &#x1f31f; 每日一练刷题专栏 &#x1f31f; Golang每日一练 专栏 Python每日一练 专栏 …

红黑树RBT(Read Black Tree)小结

顺序搜索 线性搜索&#xff1a;跟队列中一个个元素顺序比较时间复杂度是O(n)存在的问题&#xff1a;元素多时搜索很慢 二分搜索(Binary Search) 队列中的元素有序&#xff0c;比如从小到大每次把队列一分为二&#xff0c;每次跟队列中的中间元素比较时间复杂度是O(log2/logn…

vue尚品汇商城项目-day01【2.vue-cli脚手架初始化项目的其他配置】

文章目录2.项目的其他配置2.1 项目运行时&#xff0c;让浏览器自动打开2.2 关闭eslint的校验功能、配置map不打包、配置默认打开浏览器显示无法访问的问题2.3 给src文件夹简写方法&#xff0c;配置别名&#xff0c;方便引入资源本人其他相关文章链接2.项目的其他配置 2.1 项目…

进入软件测试行业需要学习多久

软件测试作为行业刚需&#xff0c;吸引着大波小伙伴想要转行&#xff0c;同时也是因为入门简单&#xff0c;学习周期相对较短。系统的培训周期在3个半月左右&#xff0c;如果是自己自学&#xff0c;那么就要最少4-6个月左右的时间~ 当下&#xff0c;软件测试就是一个不错的选择…