C中的Codechef Factorial Solution如何工作?

时间:2014-03-19 11:23:19

标签: c

我试图理解这段代码:

#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 变量,有人可以通过此循环来引导我吗?

非常感谢!

3 个答案:

答案 0 :(得分:2)

简而言之,问题是找到11000000000之间的阶乘数的零数。
现在拿一支铅笔和一张纸。从1开始。从14,没有0。首先0发生在5!。接下来是10!,然后是15!, 20!, .....。这意味着零的数量以5的间隔增加。

进入循环

for (j=5;j<=i;j*=5)
{
      p=p+i/j;
}

在此处查看i代表N(请参阅问题)。由于零的数量以5的间隔增加,j初始化为5j将增加为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 FactorialFactorials and Trailing Zeroes中概述的阶乘的尾随零的数量,则此算法更有意义。基本上依赖于您在因子扩展中考虑52的所有产品所需的洞察力,以发现最终会有多少个零。

查找x!中尾随零数的算法归结为:

  1. 寻找5
  2. 的连续权力
  3. x除以结果,将截断的结果添加到总数
  4. 当除法结果小于1时停止或在此特定情况下我们知道当结果大于x
  5. 会发生这种情况

    因此,如果回到代码,我们可以找到以下步骤:

             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中。

  • 循环1:j=5p+=i/5计算5范围内[1, i]可以整除的数字
  • 循环2:j=25p+=i/25计算25范围内[1, i]可以整除的数字(注意这些数字已在循环1中计算过一次)
  • 循环3:j=125p+=i/125计算125范围内[1, i]可以整除的数字(注意这些数字已在循环1中计算两次, 2)
  • ....