蓝桥杯题库练习3500阶乘求和

不要用循环到202320232023求阶乘,数值太大,会超时。

找规律:

1!=1;2!=2;3!= 6;4!=24;5!=120(1个0);6!=720;7!=5040;8!=40320;9!=362880;

10!=3628800(2个0);11!=39916800;12!=479001600;13!=6,227,020,800;14!=87178291200;15!=1,307,674,368,000(3个0)

1!到9!的值较小且末尾没有很多个零,从10!起得到的阶乘值会有多个末尾0,因为每个阶乘相乘过程中会有多个2、5因子(可以理解为2、5的倍数)相乘得到10,即在末尾增0。

找出那个n0,即n0!末尾有9个0,则在n>n0之后的阶乘对S的末尾9位无影响。

可以认为:阶乘的末尾零的数量取决于因子 5 的数量,因为因子 2 的数量总是超过因子 5 的数量。注意这里的因子5,是每多一个5,5,25(5*5),125(5*25)

由公式可知10!起有2个0,15!起有3个0,类推得20!为4个0,25!为6个0,30!有7个0,35!有8个0,40!有9个0,45!起有10个0

则只计算1!到39!即可

代码:

#include <iostream>
using namespace std;
int main()
{
  // 请在此输入您的代码
  
  long long S=0;
  for(int i=1;i<40;i++)
  {
    long long n=1;
    for(int j=1;j<=i;j++)
    {
      n*=j;
      n%=1000000000;//注意这里,一定要对每个n取余避免溢出
    }
    
    S+=n;
    
  }
  cout<<S%1000000000;

  return 0;
}

注意:

首先,阶乘的值增长非常快:

  • 10!=3628800
  • 20!≈2.43×10^{18}
  • 30!≈2.65×10^{32}
  • 39!≈6.24×10^{46}

这样大的数字对于计算机中的标准数据类型是很难处理的。如果你使用例如 long long (在大多数编译器中是 64 位),它的最大值大约是 1.84×10^{19}。当计算到 20!或更大的 n!时,就可能会很轻易超出 long long 能表示的范围。 

如果没有 n %= 1000000000,在 n *= j 这一行,当 n 增大到超过 long long 的范围时,会发生整数溢出。溢出后得到的值将是不可预测的,通常是在该类型能够表达的最大值周围“绕回”到负数或小数,这导致后续的结果也是错误的。

通过在每次计算后取模,保持 n在 0 到 999999999的范围内,确保每次的计算结果都是有效和准确的。这样能有效避免整数溢出,同时,也能保持程序在整次计算过程中的稳定性。

若其中任何一个 n 由于溢出导致了错误的值,那么 S 将会反映这种错误,最终导致输出结果也是错误的。

评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值