为什么我在这里没有得到任何输出?

时间:2015-11-03 01:58:58

标签: c

在项目Euler中,存在一个题为“最小倍数”的问题。我试图解决它并尝试为该问题编写代码。但我没有得到任何输出! 问题描述如下:

2520是可以除以1到10之间的每个数字而没有任何余数的最小数字。 可以被1到20的所有数字整除的最小正数是什么?

所以我为这个问题编写了代码。首先,我编写一个代码来检查它是否正确2520是可以除以1到10之间的每个数字而没有任何余数的最小数字。对于那个问题,我写下面的程序。

#include <stdio.h>
#include <stdlib.h>
#include <string.h>
#include <math.h>

int main()
{
  int i,j,count = 0,num;

  for (i = 1; count != 10; i++) {
    count = 0;

    for (j = 1; j <= 10; j++)
      if(!(i % j))
        count++;

    if( count == 10 )
      num = i;
  }

  printf("%d\n",num);
}

我得到了这个问题的理想输出。但每当我编写此代码以找到可被1-20整除的值而没有任何余数时,我就找不到任何输出。我编写了下面的代码并编译并运行,但它没有给我任何结果。但程序仍然在运行,每当我按 Control + C ,程序就会终止。

问题的代码.....

#include <stdio.h>
#include <math.h>
#include <stdlib.h>
#include <string.h>

int main()
{
  long long int i,j,count = 0,num;

  for (i = 1; count != 20; i++) {
     count = 0;

     for (j = 1; j <= 20; j++)
       if (!( i % j))
         count++;

     if (count == 20)
       num = i;
  }

  printf("%lld\n",num);
}

问题出在哪里?

1 个答案:

答案 0 :(得分:2)

如果我要这样做,我会做一些不同的事情。让我们首先考虑一个不是最小的数字,但显然是正确的,并且非常容易计算:如果你只是乘以2 * 3 * 4 * 5 * 6 * ... N ,你得到的数字明显可以被所有这些较小的数字整除。

现在,问题是我们如何生成较小的数字,其基本特征相同,可以被所有较小的数字整除。我们可以通过观察(例如)10个因子到2 * 2 * 5来做到这一点,所以(例如)我们不必分别乘以2,4或5来得到结果。可以被2,4和5整除。

因此,我们可以得到我们的数字列表,以及每个数字的素数因子:

10: 2 * 2 * 5
9:  3 * 3
8:  2 * 2 * 2
7:  7
6:  2 * 3
5:  5
4:  2 * 2
3:  3
2:  2
1:  1

然后我们可以在列表中稍后出现的列表中删除因子(但只能达到列表中早先出现的次数)。这给了我们这样的东西:

10: 2 * 2 * 5
9:  3 * 3
8:  2
7:  7
6:  -
5:  -
4:  -
3:  -
2:  -

将剩下的东西(2 * 2 * 5 * 3 * 3 * 2 * 7)相乘,得到我们预期的2520.

将相同的技术应用于20,我们得到如下列表:20 19 9 17 4 7 13 11。将其乘以,我们得到232792560

如果您更关心效率,您可以(例如)使用Euclid算法来计算一对数字的GCD。我们在这里计算的是一对数字的最小公倍数,它是数字除以它们的GCD的乘积。然后我们可以重复使用我们之前的LCM作为GCD的输入之一,因此我们最终得到的代码如下:

unsigned LCM = max;

for (int i = max - 1; i > 1; i--)
    LCM = i * LCM / GCD(i, LCM);

还有很多方法可以计算GCD。一个简单,众所周知且相当有效的算法是Euclid算法,它看起来像这样:

unsigned GCD(unsigned u, unsigned v) {
    while ( v != 0) {
        unsigned r = u % v;
        u = v;
        v = r;
    }
    return u;
}

使用这个,计算每个N从5到30(并将它们写入文件)的1..N的LCM大约需要3毫秒才能在我正在使用的机器上使用(虽然我怀疑更多仔细的时间会证明它真的比那快。)