小蓝有一个超大的仓库,可以摆放很多货物。
现在,小蓝有
n
箱货物要摆放在仓库,每箱货物都是规则的正方体。小蓝
规定了长、宽、高三个互相垂直的方向,每箱货物的边都必须严格平行于长、
宽、高。
小蓝希望所有的货物最终摆成一个大的长方体。即在长、宽、高的方向上
分别堆
L
、
W
、
H
的货物,满足
n
=
L
×
W
×
H
。
给定
n
,请问有多少种堆放货物的方案满足要求。
例如,当
n
= 4
时,有以下
6
种方案:
1
×
1
×
4
、
1
×
2
×
2
、
1
×
4
×
1
、
2
×
1
×
2
、
2
×
2
×
1
、
4
×
1
×
1
。
请问,当
n
= 2021041820210418
(注意有
16
位数字)时,总共有多少种
方案?
思路:因为他给的数据很大,所以暴力肯定会超时,所以我们需要剪枝和优化
我们先算出按递增排序的三个数a<=b<=c,然后判断,如果是三个不同的数的话摆法是三的阶乘,如果是两个不同的数的话摆法是三,如果相等的话摆法是一
一共有三个数,所以第一层循环i,如果i*i*i>n的话就可以结束循环了,并且在运算的时候判断一下i是否是n的因数,如果不是直接continue;
第二层循环是j*j>n/i的时候停止循环,判断一下j是不是n/i的因数,如果不是直接continue
第三层直接算出k=n/i/j,因为已经判断了j是n/i的因数,所以k算出来直接是整数,然后判断这个序列是否满足i<=j<=k,如果不满足直接continue,如果满足再判断他是上述三个里面的什么类型,最后加上相应的摆法就可以了。
#include<iostream>
#include<map>
using namespace std;
int main(){
long long int x=2021041820210418,con=0;
for(long long i=1;i*i*i<=x;i++){
if(x%i!=0)continue;
long long int q=x/i;
for(long long j=i;j*j<=q;j++){
if(q%j!=0)continue;
long long int k=q/j;
if(i>k||j>k)continue;
if(i!=j&&i!=k&&j!=k){
con+=6;
}else if(i==j||i==k||j==k){
con+=3;
}else{
con++;
}
}
}
printf("%lld",con);
return 0;
}