题目描述
小蓝有一个超大的仓库,可以摆放很多货物。
现在,小蓝有 n 箱货物要摆放在仓库,每箱货物都是规则的正方体。小蓝规定了长、宽、高三个互相垂直的方向,每箱货物的边都必须严格平行于长、宽、高。
小蓝希望所有的货物最终摆成一个大的长方体。即在长、宽、高的方向上分别堆 L、W、H 的货物,满足
n = L \times W \times H给定 n,请问有多少种堆放货物的方案满足要求。
例如,当 n=4 时,有以下 6 种方案:
1\times1\times4、1\times2\times2、1\times4\times1、2\times1\times2、2\times2\times1、4\times1\times1请问,当
n = 2021041820210418
(注意有 16 位数字)时,总共有多少种方案?
提示:建议使用计算机编程解决问题。
答案提交
这是一道结果填空的题,你只需要算出结果后提交即可。本题的结果为一个整数,在提交答案时只填写这个整数,填写多余的内容将无法得分。
运行限制
最大运行时间:1s
这道题需要求这16位数字的所有的的因数,我们一开始会想使用遍历的形式计算,但光遍历原数字就要10^16次计算,如果按照C语言每秒计算的位数换算,遍历全部数字需要1000多天,这显然超时,所以我们不能有任何遍历它的行为,那么我们从因数的角度出发,因数总是成对的,如果我们假设一个因数小于sqrt(n),那么有
r \le \sqrt N
变形有
N/r \ge \sqrt N
我们就能发现与这个因数成对的另外一个因数分布在大于sqrt(n),如果我们求得小于sqrt(n)的因数a,那么与之配对的另一个因数用n/a就能求出,但是我们要注意a=n/a的情况,避免重复计算,开根之后数值规模立刻降到10^8,这是允许遍历的,所以遍历开根是一种很好的求因数的方法
求出来两个不同的因数之后放入因数桶(通常因数的数量不大,10^4可满足)中,然后遍历两层因数桶,一层从0到X(因数桶元素个数),二层从0到X,通过两层循环就能得到两个因数的全部组合(a1,a2),利用n%a1*a2==0就能求得三个因数中的最后一个元素,至此就能把这个数的全部因数组合求出来
下面是代码展示:
<code>#include <stdio.h>
const long long int N = 2021041820210418;
long long fac[10000] = {0}; //因数桶
int main(void)
{
long long int r1,x=0;
for(r1 = 1;r1*r1<=N;r1++)//开方避免使用math.h的方法,收集因数
{
if(N%r1 == 0)
{
fac[x++] = r1;
if(r1 != N / r1)
{
fac[x++] = N / r1;//如果r1是因素,那么N/r1也是因数
}
}
}
long long ans = 0,r2,r3;
for(r2=0;r2<x;r2++)
{
for(r3=0;r3<x;r3++)
{
long long a = fac[r2];
long long b = fac[r3];
if(a > N / b) continue;
if(N%(a*b) == 0)
{
ans++;
}
}
}
printf("%lld",ans);
return 0;
}
</code>
评论(0)
暂无评论