阶乘约数——蓝桥杯python组国赛题(C++唯一分解定理)

Posted 布布要成为最负责的男人

tags:

篇首语:本文由小常识网(cha138.com)小编为大家整理,主要介绍了阶乘约数——蓝桥杯python组国赛题(C++唯一分解定理)相关的知识,希望对你有一定的参考价值。

题目描述
本题为填空题,只需要算出结果后,在代码中使用输出语句将所填结果输出即可。

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

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

运行限制
最大运行时间:1s
最大运行内存: 128M

分析

这道题是一个唯一分解定理的运用,唯一分解定理通常用来解决大数相除这类型的题,给出唯一分解定理的定义:

任何一个大于1的数,都可以唯一分解成若干个质数的乘积

注意该定理的性质:存在性、唯一性

这是一种数学思维,自行证明起来也容易,想看那种严谨的数学思维推导的证明方法自行去搜索即可。

给出唯一分解定理的算法:

vector<int>v;//存储唯一分解定理的分解值
inline void dev(int n)
	int c=sqrt(n);//这里要单独提出来,否则下面for循环的时候n会变
	for(int i=2;i<=c;++i)
		//当n整除i的时候,就一直除到这个没办法再除为止
		while(n%i==0)n/=i,v.push_back(i);
		//容易发现,经过这样的处理,绝对不会出来i是非素数的情况下n%i=0,
		//比如i=2的时候被n整除,n除i到没有办法再除以之后,n绝对不可能在之后整除4
	if(n)//可能整除完还剩下一个数字,这个数字一定是素数
		v.push_back(n);

放到这道题,我们如果暴搜,基本上是跑不出来的,就算能跑出来,还得要去重,除此之外,数字可能很大,long long也是存不下去的。

这里遇到的问题,就是大数相除问题:通常情况,我们构造出来一个数字num以后需要验证(n!)%num=0,然后这样的数连存储都做不到。

而考虑一种思维,如果这个数能被n!整除,那么我们肯定是被其中的所有数(1、2、…、n)的所有素数因子的若干个组成,而对于100!,我们可以把1到100中的每个数分解质因数,通过这些质因数很容易调配出其约数。

代码如下:

#include<bits/stdc++.h>
#define ll long long 
using namespace std;
int cnt[105];
inline void dev(int n)
	int c=sqrt(n);
	for(int i=2;i<=c;++i)
		while(n%i==0)n/=i,cnt[i]++;
	if(n)cnt[n]++;

int main()
	for(int i=2;i<=100;++i)dev(i);
	ll ans=1;
	for(int i=2;i<=100;++i)ans*=(cnt[i]+1);//+1的原因是某个质因数完全可以不用选,也是一种情况(一个都不选代表的是选1这个非质因数)
	cout<<ans<<endl;
 

第十一届蓝桥杯(国赛)——阶乘约数

问题描述
定义阶乘 n! = 1 × 2 × 3 × ··· × n。

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

答案提交
这是一道结果填空的题,你只需要算出结果后提交即可。
本题的结果为一个整数,在提交答案时只填写这个整数,填写多余的内容将无法得分。

思路

质因数分解,每个数可以分成有限个质数相乘,X = p1^α1 ∗ p2^α2 …… ∗ pk^αk。
那么求X=1!*2! *…*100!,的约数先将X分解成质数相乘,而它的每一个约数的构成则为-----从每个质数次方选一种可能最低为0次方,最高为组成X质数的次方,每个质数贡献(a+1,假设X可分解出该质数a次方),总的约数个数则为约数个数 = (a1 + 1)(a2 + 1)……(ak + 1)

Code

#include <iostream>
using namespace std;
typedef long long ll;

int p[1000005];

int main()

    for(int i=2;i<=100;i++)
    
      int n=i;

      for(int j=2;j*j<=n;j++)
      
          while(n%j==0)
          
              p[j]++;
              n/=j; 
          
      
      if(n!=1)p[n]++;

    
    ll ans=1;
    for(int i=2;i<=100;i++)
    
        ans*=(p[i]+1);
    
    cout<<ans;


以上是关于阶乘约数——蓝桥杯python组国赛题(C++唯一分解定理)的主要内容,如果未能解决你的问题,请参考以下文章

第十一届蓝桥杯(国赛)——阶乘约数

第十一届蓝桥杯(国赛)——阶乘约数

蓝桥杯Web2022年第十三届蓝桥杯Web大学组国赛真题解析

蓝桥杯第十三届Web组国赛天气趋势A详细题解

第十三届蓝桥杯c++b组国赛题解(还在持续更新中...)

第十三届蓝桥杯Java B 组国赛 C 题——左移右移(AC)