luoguP1134 【阶乘问题】

P1134 阶乘问题

传送门

题目描述

也许你早就知道阶乘的含义,N阶乘是由1到N相乘而产生,如:

12! 12 ! = = 1 x 2 2 x 3 x 4 4 x 5 x 6 6 x 7 x 8 8 x 9 x 10 10 x 11 11 x 12 12 = = 479,001,600

12 12 的阶乘最右边的非零位为 6 6

写一个程序,计算N(1<=N<=50,000,000)阶乘的最右边的非零位的值。

注意: 10,000,000 10 , 000 , 000 !有 2499999 2499999 个零。

输入输出格式

输入格式:

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

输出格式:

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

输入输出样例

输入样例#1:

12

输出样例#1:

6 6

说明

USACOTrainingSection3.2

小菜鸡好久没有和大家见面了,今天感到格外开心。

来,帮小菜鸡再挑战新高度。

上个星期,和一帮师兄(都是大神)听课。

其中有一道题比较感兴趣。

那就是本题了。

难度为 普及/提高- 。

小菜鸡一开始没开题觉得很难,毕竟是和一群 dalao d a l a o 上课。

但一看题其实并没有想象的那么难,开来审题还是非常重要的。

这道题小菜鸡觉得和下面这道小学生赛题目,有点相似。

1.连续零(难度系数:容易)
(1.pas/cpp/c)

【题目描述】
输入两个正整数a和b,s为a到b之间(包含a、b)所有整数的乘积,求s末尾从个位开始有多少个连续的0。
比如a=1,b=7,那么s=1*2*3*4*5*6*7=5040,答案就是1,不是2。

【输入格式】
一行两个正整数,分别表示a和b(1<=a,b<=10^6)。

【输出格式】
输出一行一个整数,即0的个数。

【输入输出样例1】
lxl.in  lxl.out
1 10    2

【输入输出样例2】
lxl.in  lxl.out
4 25    6

【数据范围】
1<=a,b<=1000 000

那我们先从这道题入手。

首先审题,非常重要。

主要讲的是: a a b的乘积,末尾有几个 0 0

那末尾0怎么产生的呢?

2 2 × 5 = = 10

也就是说,找 2 2 5的个数,然后比较谁少,就是答案。

忘了告诉大家这道题有个坑, a a 不一定比b小,交换一下就可以了。

参考程序:

#include<cstdio>//调用      scanf      库
long long a,b,t,x,y,s1=0,s2=0;//竞赛最好开      long long      ,避免数据太大的情况
int main()//主函数
{
    scanf("%lld %lld",&a,&b);//输入
    //注意      longlong      地址符是      %lld
    if(a>b)t=a,a=b,b=t;//坑的处理
    for(long long i=a;i<=b;i++)
    {
        x=i,y=i;
        while(x%2==0)x/=2,s1++;
        while(y%5==0)y/=5,s2++;
    }
    //算出2和5的个数
    if(s1<s2)printf("%lld",s1);
    else printf("%lld",s2);
    //输出小的
    return 0;
}

回归正题,题目类似

不过洛谷上是 n! n ! ,就没有刚刚的坑点了。

其实,刚刚有个优化,直接判断 10 10

因为, 2 2 5才得到 10 10 ,那个少一个都不行,所以自然得出少的个数。

来,一起大代码:

#include<cstdio>//调用      scanf      库
#define ll long long//long long      可开可不开,不过小菜鸡喜欢
ll n,ans=1;//ans      做累乘
int main()//美好的开始
{
    scanf("%lld",&n);//完美输入
    for(ll i=1;i<=n;i++)//开始n的阶乘
    {
        ans*=i;//累乘
        while(ans%10==0)ans/=10;//能被10整出就除
        ans%=10000000;//记得%10000000,错了可不要怪小菜鸡哦
    }
    printf("%lld",ans%10);//注意最后要%10,想了大约半个小时
    return 0;//下次再见
}
  • 1
    点赞
  • 0
    收藏
    觉得还不错? 一键收藏
  • 0
    评论

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

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

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值