阶乘问题 n!后最右边非0的数

 阶乘问题

时间限制: 1 Sec  内存限制: 128 MB
提交: 66  解决: 13
[提交][状态][讨论版]

题目描述

也许你早就知道阶乘的含义,N阶乘是由1到N相乘而产生,如:
    12! = 1 x 2 x 3 x 4 x 5 x 6 x 7 x 8 x 9 x 10 x 11 x 12 = 479,001,600
12的阶乘最右边的非零位为6。
    写一个程序,计算N(1<=N<=50,000,000)阶乘的最右边的非零位的值。
注意:10,000,000!有2499999个零。

输入

仅一行包含一个正整数N。

输出

单独一行包含一个整数表示最右边的非零位的值。

样例输入

12

样例输出

6

#include <cstdio>
#include <algorithm>
#define ll long long
#define maxn 800010
#define lson l,m,rt<<1
#define rson m+1,r,rt<< 1 | 1
using namespace std;
int s[100];
int main(){
    int num,n,add,pai[4]={6,2,4,8};
    while(~scanf("%d",&n)){
        num=n;
        add=0;
        while(num){
            if(num%5==2){
                add+=1;
            }
            else{
                if(num%5==4)
                    add+=2;
            }
            add+=num/5;
            num/=5;
        }
        if(n>1){
            printf("%d\n",pai[add%4]);
        }
        else printf("1\n");
    }
}

 

转载于:https://www.cnblogs.com/acmtime/p/5762883.html

这是一个比较有趣的问题。我们可以通过寻找规律,简化计算过程。 首先,我们知道,一个阶乘末尾有多少个零,取决于它可以分解出多少个因子 10,而 10 可以分解为 2 和 5 相乘得到。因此,我们只需要计算 N! 中因子 2 和因子 5 的个,取其中较小的那个作为 N! 末尾的零的个。 但是,这个问题要求的并不是末尾的零的个,而是最右边。我们可以通过对每个因子进行分解,找出相乘后最右边的规律。 我们可以发现,对于一个 x,如果它的最右边是 k,那么 x 乘以任何一个以 5 为末尾的字都会让最右边变成 k。因此,我们只需要找到 N! 中所有因子中最右边,然后将它们依次乘以 1、2、3、4……N 中末尾为 1、3、7、9 的字,找到其中最右边即可。 下面是 Python 代码实现: ```python def rightmost_nonzero_digit(n): # 计算因子 2 和因子 5 的个 num_2, num_5 = 0, 0 for i in range(1, n+1): x = i while x % 2 == 0: num_2 += 1 x //= 2 while x % 5 == 0: num_5 += 1 x //= 5 # 计算所有因子中最右边 last_digit = 1 for i in range(1, n+1): x = i while x % 10 == 0: x //= 10 last_digit = (last_digit * x) % 10 # 将最右边乘以 1、2、3、4……N 中末尾为 1、3、7、9 的字,找到其中最右边 if num_2 > num_5: for i in [1, 3, 7, 9]: if (i * pow(2, num_2 - num_5, 10) * last_digit) % 10 != 0: return (i * pow(2, num_2 - num_5, 10) * last_digit) % 10 else: for i in [1, 3, 7, 9]: if (i * pow(5, num_5 - num_2, 10) * last_digit) % 10 != 0: return (i * pow(5, num_5 - num_2, 10) * last_digit) % 10 ``` 注意,在计算最右边时,我们需要用到取模运算,以避免超出计算机能处理的整范围。同时,我们还需要注意一些细节,例如排除因子中末尾为 0 的字,以及在计算 2 和 5 的个时,我们只需要统计它们在因子中的出现次,而不是每个因子都进行分解。
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值