项目欧拉练习5方法

时间:2012-05-06 18:27:37

标签: c

问题:2520是可以除以1到10之间的每个数字而没有任何余数的最小数字。

从1到20的所有数字均可被整除的最小正数是多少?

所以,我试图在项目euler上做练习5,然后我出来了这段代码:

#include <stdio.h>
#define TRUE 1
#define FALSE 0

int main () {
   int n, fnd = FALSE, count, i; 

   for (i = 1; fnd == FALSE; i++) {       
      count = 0;
      for (n = 1; n <= 20; n++) {
         count += i % n;
      }
      printf ("testing %d, count was: %d\n", i, count);
      if (count == 0) {
         fnd = TRUE;
         printf ("%d\n", i); 
      }
   }
   return 0;
}

我相信我的apporach是正确的,它肯定会找到可以被1到20整除的数字。但它已经计算了5分钟,但仍然没有结果。我的方法是否正确?如果是,那么还有另一种方法吗?我想不出另一种方法来解决这个问题,非常感谢提示。提前谢谢。

编辑: 所以,基于我们给你的建议,我想出来了,非常感谢你! 因此,它仍然是蛮力,但它不是在最后一个数字上加1,而是现在增加2520,这是1到10的最小公倍数。因此,计算2520的倍数的余数之和是否从11到11 20是0.由于2520已经可以被1到10整除,我只需要除以11到20。

#include <stdio.h>
#define TRUE 1
#define FALSE 0

int main () {
   int n, fnd = FALSE, count, i; 

   for (i = 2520; fnd == FALSE; i = i + 2520) {       
      count = 0;
      for (n = 11; n <= 20; n++) {
         count += i % n;
      }
      printf ("testing %d, count was: %d\n", i, count);
      if (count == 0 && i != 0) {
         fnd = TRUE;
         printf ("%d\n", i); 
      }
   }
   return 0;
}

非常感谢你,没有你的帮助,我不会解决它:) PS:现在计算时间不到10秒。

7 个答案:

答案 0 :(得分:3)

你的方法花了太长时间,因为它是一种蛮力的解决方案。你需要有点聪明。

我的暗示是:一个数字可以被另一个数字整除,这意味着什么?或者每个数字低于一定数量?这些数字的素数因子是否存在共性? Wikipedia page on divisibility应该是一个很好的起点。

答案 1 :(得分:3)

提示:你应该查找“最不常见的倍数”。


下一个提示:

  1. 答案是数字1,2,3,......,20的最小公倍数(LCM)。
  2. n 数字的LCM可以顺序找到:如果LCM(1,2)= x ,则LCM(1,2,3)= LCM( > x ,3);如果LCM(1,2,3)= y ,则LCM(1,2,3,4)= LCM( y ,4)等等。所以它足以知道如何找到任何2个数字的LCM。
  3. 为了找到2个数字的LCM,我们可以使用以下公式:LCM( p q )= pq / GCD( p q ),其中GCD是最大公约数
  4. 为了找到GCD,有一个众所周知的Euclid算法(也许是地球上第一个非平凡的算法)。

答案 2 :(得分:1)

我认为你应该首先计算每个数字的素数因子从2到20。 由于所需的数字应该可以被1到20的每个数字整除,所以它也必须 可以被这些数字的每个主要因素整除。

此外,重要的是跟踪素因子的多重性。 例如,4 = 2 * 2,因此所需的数字必须可被2 * 2整除。

答案 3 :(得分:0)

我很快就用Python 3烘焙了一些东西:

primary_list = []
for i in range(2, 4097):
    j = i
    k = 2
    delta_list = primary_list[0:]
    alpha_list = []
    while j > 1:
        if j % k == 0:
            j /= k
            alpha_list.append(k)
            k = 2
        else:
            k += 1
    for i in alpha_list:
        try:
            delta_list.remove(i)
        except:
            primary_list.append(i)
final_number = 1
for i in primary_list:
    final_number *= i
print(final_number)

这在机器下仅需几秒钟即可完成计算。 Python非常适合抽象数字。这项工作的最佳工具。

算法相对简单。我们有一个基本列表 primary_list ,我们存储了这些数字的倍数。然后是循环,我们估计我们想要计算的数字范围。我们使用临时变量 j 作为一个可以轻松划分,切割和征服的数字。我们使用 k 作为除数,从 2 开始。 delta_list primary_list 的主要工作副本,我们将数字分开,直到只剩下所需的“逻辑”为止。然后我们将这些数字添加到我们的主列表中。

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

通过将 primary_list 中的数字相乘得到最终数字。
1 * 2 * 3 * 2 * 5 * 7 * 2 * 3 = 2520

如上所述,Python _really _ 对数字很好。这是这项工作的最佳工具。这就是为什么你应该使用它代替C,Erlang,Go,D或任何其他动态/静态语言进行欧拉练习。

答案 4 :(得分:0)

我用C解决了它。下面是算法!

#include <stdio.h>
#include <stdio.h>
int main()
{
 int i;
 int count;
 for(i=21;i>0;i++)
  {  count = 0;
  for( int j=2;j<21;j++)
 {
  if (i%j!=0)
  break;
  count++;
  } 
  if (count==19)
  break;
   }

 printf("%d\n",i);
 return 0;
   }

答案 5 :(得分:0)

关于上述评论的一些想法,

@ pg190你说“它真的只需要被1到20之间的素数整除,即2,3,5,7,11,13,17,19”。 取9699690,不会偏离1-20的所有值。

所以这可能是一个很好的解决方案,

给定数字[1-20]

最小公倍数可以如下计算。

实施例。数字2,6,9

在素数乘法中表达它们 2 2

6 2 3

9 3 3

LCM =每个素数的最高功率的倍数。     = 2 * 3 ^ 2 = 18

这可以通过将每个数字表示为素数乘法来解决手头的问题 然后做这个数学。

答案 6 :(得分:0)

$num=20;
        for($j=19;$j>1;$j--)
        {
            $num= lcm($j,$num);
        }
        echo $num;
        function lcm($num1, $num2)
        {
            $lcm = ($num1*$num2)/(gcd($num1,$num2));
            return $lcm;
        }
        function gcd($n1,$n2)
        {
            $gcd=1;
            $min=$n1;
            if($n1>$n2)
            {
                $min=$n2;
            }
            for($i=$min;$i>1;$i--)
            {
                if($n1%$i==0 && $n2%$i==0)
                {
                    $gcd*=$i;
                    $n1/=$i;
                    $n2/=$i;
                }
            }
            return $gcd;
        }

在php中解决