我试图理解这段代码:
#include<stdio.h>
int main()
{
int j,p,k;
long long int n,i;
scanf("%lld",&n);
for(k=n;k>=1;k--)
{
p=0;
scanf("%lld",&i);
for (j=5;j<=i;j*=5)
{
p=p+i/j;
}
printf("%d\n",p);
}
return 0;
}
解决了此Codechef问题:http://www.codechef.com/problems/FCTRL
我遇到麻烦的是这个循环是如何工作的:
for (j=5;j<=i;j*=5)
{
p=p+i/j;
}
为什么 j 变量设置为5,如果我将值60赋予 i 变量,有人可以通过此循环来引导我吗?
非常感谢!
答案 0 :(得分:2)
简而言之,问题是找到1
到1000000000
之间的阶乘数的零数。
现在拿一支铅笔和一张纸。从1
开始。从1
到4
,没有0
。首先0
发生在5!
。接下来是10!
,然后是15!, 20!, .....
。这意味着零的数量以5
的间隔增加。
进入循环
for (j=5;j<=i;j*=5)
{
p=p+i/j;
}
在此处查看i
代表N
(请参阅问题)。由于零的数量以5
的间隔增加,j
初始化为5
,j
将增加为5
的倍数。
现在简单的规则是 N!
的十进制表示中的尾随零的数量只是5
中素因子N!
的多重性。
在声明p=p+i/j;
中,遵循相同的规则。该计划的作者将j
增加5
,直至N/j >= 5
离开N
(即i
)。
N = i = 30
p = 30/5 + 30/(5*5) = 6 // 30/25 is 1 and does not satisfying the condition N/j >= 5
答案 1 :(得分:2)
如果您了解他们用于查找Trailing zero Factorial和Factorials and Trailing Zeroes中概述的阶乘的尾随零的数量,则此算法更有意义。基本上依赖于您在因子扩展中考虑5
和2
的所有产品所需的洞察力,以发现最终会有多少个零。
查找x!
中尾随零数的算法归结为:
5
x
除以结果,将截断的结果添加到总数1
时停止或在此特定情况下我们知道当结果大于x
时因此,如果回到代码,我们可以找到以下步骤:
step 3
| step 1
V V
for (j=5;j<=i;j*=5)
{
p=p+i/j; // step 2
}
答案 2 :(得分:1)
这段代码:
p=0;
scanf("%lld",&i);
for (j=5;j<=i;j*=5)
{
p=p+i/j;
}
计算5
中所有整数中的因子[1, i]
的数量,并将结果存储在p
中。
j=5
,p+=i/5
计算5
范围内[1, i]
可以整除的数字j=25
,p+=i/25
计算25
范围内[1, i]
可以整除的数字(注意这些数字已在循环1中计算过一次) j=125
,p+=i/125
计算125
范围内[1, i]
可以整除的数字(注意这些数字已在循环1中计算两次, 2)