解题思路 — C++

萌新:这题我会,只要将1∼n 的每个数乘起来就好了。

大佬:那你算算 21!等于多少?

萌新: 我算算吼。21!=1×2×3×...×21 = 51090942171709440000

大佬: ??你怎么算的这么快?

萌新: 因为我用了计算器...

大佬: ......,那你发现什么了没有?

萌新: 51090942171709440000这个数太大了,C++的unsigned long long 最大值也才2^{64},存不下。

大佬: 是吧,所以你的想法是美好的,只可惜C++的整型变量根本...

萌新: 哦那我可以用 __int128

大佬: ......,__int128目前还有很多OJ不支持,就算支持,那 1000!1000! 你总没办法存了吧。

萌新: em,那该怎么办?

大佬: 别急,你先回想一下你小学老师教你的乘法是什么样的?

萌新: 小学学的乘法法大概是:相同数位对齐,然后选择其中一个数的各位数字乘以另一个数,并 把相乘的结果累加...

大佬: 是的,那么你就可以模拟这个操作:

  1. 定义一个大数组A[]来存大数,数组的一个元素存大数的一位。例如A[0]A[0]存个位,A[1]A[1]存十位,A[2]A[2]存百位,等等。
  2. 那么A[]A[]需要定义成多大?也就是说,1000!1000!有多少位?可以自己估计,不过,可以用 windows 自带的计算器能直接算出来,1000! ≈ 4×10^{2567}1000!≈4×102567。代码中定义一个更大的A[10000]。
  3. 模拟乘法计算,处理进位:例如356×8356×8。先计算个位的6×86×8,得4848,其中个位的88等于 48%10=848,进位的44等于48/10=448/10=4。见我代码中的10\sim 1310∼13行,这几行实际上是处理了两个数的乘法,请仔细分析这几行代码。
  4. 按3的计算方法,计算n!。第8行的i遍历了1∼n,计算n!。
  5. 最后打印是,从最高位开始打印。先找到最高位,即第一个不等于0的数,然后从高位往最低位打印。

好了,接下来请你自己编码完成这道题。下面的是我的代码,你可以作为参考。注意:代码第 33 行的 intA[] 是个大静态数组,应该定义在全局。如果定义在函数内部,有些编译器会出错哦。

萌新: 了解!不过大佬,这复杂度不会太高了吗?

大佬: 当然不会,你看我代码的第8行和10行,代码共循环计算了10000×n = 10000×1000 =10000×n=10000×1000= 1千万次,正好不会超时。这也是题目为什么要你计算1000!,若计算更大的数,用这个代码就可能超时了。

萌新: orz。

#include <bits/stdc++.h>
using namespace std;
int A[10000] = {0};  //存结果,注意大的静态数组要定义在全局
int main(){
    int n;
    cin >> n;

    A[0] = 1;
    for(int i = 1;i <= n;i++){
        int carry = 0;            //进位
        for(int j = 0;j < 10000;j++){
            A[j] = A[j] * i + carry;
            carry = A[j] / 10;
            A[j] = A[j] % 10;
        }
    }
    int last;
    for(int i = 10000 - 1;i >= 0;i--){
        if (A[i] != 0){
            last = i;
            break;
        }
    }
    for(int i = last; i >= 0;i--)
        cout << A[i];

    return 0;
}

  • 0
    点赞
  • 0
    收藏
    觉得还不错? 一键收藏
  • 0
    评论

“相关推荐”对你有帮助么?

  • 非常没帮助
  • 没帮助
  • 一般
  • 有帮助
  • 非常有帮助
提交
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值