P1134 阶乘问题
传送门
题目描述
也许你早就知道阶乘的含义,N阶乘是由1到N相乘而产生,如:
x x x x x x x x x x x
的阶乘最右边的非零位为 。
写一个程序,计算 阶乘的最右边的非零位的值。
注意: !有 个零。
输入输出格式
输入格式:
仅一行包含一个正整数 。
输出格式:
单独一行包含一个整数表示最右边的非零位的值。
输入输出样例
输入样例#1:
输出样例#1:
说明
小菜鸡好久没有和大家见面了,今天感到格外开心。
来,帮小菜鸡再挑战新高度。
上个星期,和一帮师兄(都是大神)听课。
其中有一道题比较感兴趣。
那就是本题了。
难度为 普及/提高- 。
小菜鸡一开始没开题觉得很难,毕竟是和一群 上课。
但一看题其实并没有想象的那么难,开来审题还是非常重要的。
这道题小菜鸡觉得和下面这道小学生赛题目,有点相似。
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
那我们先从这道题入手。
首先审题,非常重要。
主要讲的是: 到 的乘积,末尾有几个
那末尾 怎么产生的呢?
×
也就是说,找 和 的个数,然后比较谁少,就是答案。
忘了告诉大家这道题有个坑, 不一定比 小,交换一下就可以了。
参考程序:
#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;
}
回归正题,题目类似
不过洛谷上是 ,就没有刚刚的坑点了。
其实,刚刚有个优化,直接判断 。
因为, 和 才得到 ,那个少一个都不行,所以自然得出少的个数。
来,一起大代码:
#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;//下次再见
}