开启掘金成长之旅!这是我参与「掘金日新计划 · 12 月更文挑战」的第29天,点击查看活动详情
输入正整数 XX,求 XX 的大于 11 的因子组成的满足任意前一项都能整除后一项的严格递增序列的最大长度,以及满足最大长度的序列的个数。
输入格式
输入包含多组数据,每组数据占一行,包含一个正整数表示 XX。
输出格式
对于每组数据,输出序列的最大长度以及满足最大长度的序列的个数。
每个结果占一行。
数据范围
输入样例:
2
3
4
10
100
输出样例:
1 1
1 1
2 1
2 2
4 6
| 难度:中等 |
|---|
| 时/空限制:1s / 64MB |
| 总通过数:3127 |
| 总尝试数:5648 |
| 来源:《信息学奥赛一本通》 , POJ |
| 算法标签 |
分析
这题考察了算术基本定理和质因数分解以及集合的排列,首先,由算术基本定理如下图
可知,我们可以把每个数分解成这种形式,然后我们就可以发现最长因子链就是指数之和,至于个数我们可以发现,每个质因数可能重复的情况是阿尔法!种情况,所以最后有和的阶乘除以每个a的阶乘的积。
代码
#include <iostream>
#include <algorithm>
#define int long long
using namespace std;
int fact(int x){
if(x==1) return 1;
else return fact(x-1)*x;
}
struct d{
int va,cnt=0;
}divv[22];//存分解后的相应的质因子和对应的指数
int res=0;
int di(int x){
for(int i=2;i<=x/i;i++){
if(x%i==0){
divv[++res].va=i;
while(x%i==0){
divv[res].cnt++;
x/=i;
}
}
}
if(x!=1) {
divv[++res].va=x;
divv[res].cnt=1;
}
}
signed main(){
int x;
while(cin>>x){
for(int i=1;i<=23;i++){
divv[i].cnt=divv[i].va=0;
}
res=0;
di(x);
int ans1=0,ans2=1;
for(int i=1;i<=res;i++){
ans1+=divv[i].cnt;
ans2*=fact(divv[i].cnt);
// cout<<divv[i].va<<" "<<divv[i].cnt<<endl;
}
cout<<ans1<<" "<<fact(ans1)/ans2<<"\n";
}
return 0;
}
希望能帮助到大家,qaq!