USACO 阶乘

11 篇文章 0 订阅
5 篇文章 0 订阅

        题目链接:阶乘

        这个oj是我们学校自己的oj,USACO实在是太不好找题目做了,所以爬了一些题目到我们自己的oj上写题。这道题目的题意实际很简单的,求k的阶乘最后一位的非零的数字,这道题目跟hdoj 1066(poj 1150)是类似的,不过hdoj 1066(poj 1150)数据更强,用下面的代码会超时,所以会采用找循环节的方法,具体见博客hdoj 1066(poj 1150)的解法,这里只给出最好理解的代码。

        因为是要找非零位,那么我们可以知道怎样才会出现零呢?只有2和5可以去凑零,为什么4和5不可以(因为4还可以拆两个2啊),所以我们只需要找2和5出现的个数,当然2的数量远远多于5的个数,仔细想一想就知道了,所以min(sum5,sum2)全部都可以删掉了,只留下sum2-sum5个2,和剩下的数字(不能被2整除也不能被5整除),两者相乘就可以了,具体看代码

#include <bits/stdc++.h>

using namespace std;

int n,sum1,sum2;

int cal(int x){
    while(x%2 == 0){
        sum1++;
        x/=2;
    }
    while(x%5 == 0){
        sum2++;
        x/=5;
    }
    return x;
}

int quick_pow(int a,int b){
    int ans = 1;
    while(b){
        if(b&1) ans = (ans*a)%10;
        a = (a*a)%10;
        b>>=1;
    }
    return ans;
}

int main(){
    ios::sync_with_stdio(false);
    while(~scanf("%d",&n)){
        sum1 = sum2 = 0;
        int p = 1;
        for(int i = 1;i <= n;i++)
            p *= cal(i),p %=10;
        int ans = (quick_pow(2,sum1-sum2)*p)%10;
        printf("%d\n",ans);
    }
    return 0;
}

评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值