Luogu P1134 阶乘问题___推理+思维

题目大意:

计算N!的最右边的非零位的值。

1<=N<=50,000,000

题解:

N!(N≠1)的末尾只会是2,4,6,8(题目不存在0)。
因为

=表示他们的最右边非零位相同
2 * 6 = 12 = 2 , 4 * 6 = 24 = 4,
6 * 6 = 36 = 6 , 8 * 6 = 48 = 8,
即[2,4,6,8]任意一个*6都为自身
因为末尾数字只受末尾数字影响,即 i*6=i*16=i*106
然后因为4 * 2 8==4 2 * 5
所以我们将所有的2*5中的5,换成*8
因为*8有规律所以可以直接做

某dalao的题解(详):

设a==b等价于a、b去掉后缀0的尾数相等:

1.若k为4的倍数,则k5==k8

why?

设k=4n,则k5==n20,k8==n32

而20==32,于是n20==n32,证毕

2.阶乘中4的倍数不少于5的倍数

why?
对于每个a=5n<k,都必然存在b=4n<k(n为任意正整数),证毕

3.若输入大于1,则结果必为2,4,6,8之一

why?

设输入为k,则结果为k!=123...k,那么只要k>1,结果的因子中就会包含2

所以结果为偶数,而结果根据定义是一个非0值,那就只有2,4,6,8了,证毕

4.若a为偶数,则a*6==a

why?

设a=2n,则a6==n12==n10+n2==n*2==a,证毕
于是乎,设输入n,则在[1,n]中的5的倍数15,25,35...与对应的4的倍数14,24,34...相乘为(154)(258)(3512)...==(123...)(54)(58)(512)...==(123...)(84)(88)(812)*...

再把4的倍数拿出来,就相当于51015...==(123...)(888...)

而10!不含5的倍数的部分12346789==6,20!不含5的倍数的部分611121314161718*19==6,同理整十数不含5的倍数的阶乘都==6

因为n中有n/55的倍数,所以n!==(n-n%10)!+(n%10)!==6(123...n/5)(888...)(n%10(去掉5))!==(n/5)!(8^n/5)*(n%10(去掉5))!

用同样的方法再算(n/5)!,8^k的尾数是循环的,只要算8^(k%4),再暴力乘出(n%10(去掉5)),答案就出来了

代码:

#include<bits/stdc++.h>

using namespace std;

int a[4],n;

int main()
{
    scanf("%d",&n);
    if (n==1) {printf("%d\n",1); return 0;};
    a[0]=6; a[1]=8;
    a[2]=4; a[3]=2;
    int ans=1;
    while (n)
          {
               for (int i=1; i<=n%10; i++)
                    if (i!=5) ans=ans*i%10;
               n/=5;
               ans=ans*a[n%4]%10;
          }
    printf("%d\n",ans);
}
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值