C 欧拉项目练习5方法

C 欧拉项目练习5方法,c,C,问题:2520是可以被1到10之间的每个数字除的最小数,没有余数 能被1到20的所有数整除的最小正数是多少 所以,我试着在ProjectEuler上做练习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

问题:2520是可以被1到10之间的每个数字除的最小数,没有余数

能被1到20的所有数整除的最小正数是多少

所以,我试着在ProjectEuler上做练习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;
}
#包括
#定义真1
#定义FALSE 0
int main(){
int n,fnd=FALSE,count,i;
对于(i=1;fnd==FALSE;i++){
计数=0;

对于(n=1;n您的方法花费的时间太长,因为这是一个蛮力解决方案。您需要稍微聪明一点

我给你的提示是:一个数被另一个数整除意味着什么?或者低于某个数的每一个数?这些数的素数因子是否有共性?这应该是一个很好的起点。

提示:你应该查找“最小公倍数”


下一个提示:

  • 答案是数字1、2、3、…、20的最小公倍数(LCM)
  • 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就足够了
  • 为了找到两个数的LCM,我们可以使用以下公式:LCM(p,q)=pq/GCD(p,q),其中GCD是最大公因数
  • 为了找到GCD,有一个著名的欧几里德算法(可能是地球上第一个非平凡算法)

  • 我认为你应该从计算每个数的素数因子开始,从2到20。 由于所需的数字应该可以被1到20之间的每个数字整除,因此它还必须 可以被这些数字的每个素数因子整除

    此外,跟踪主要因素的多样性也很重要。
    例如,4=2*2,因此所需的数字必须能被2*2整除。

    我用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_列表是主_列表的主要工作副本,我们将一个数字接一个数字分开,直到只剩下所需的“逻辑”。然后我们将这些数字添加到主列表中

    1:1
    2:21
    3:31
    4:221
    5:51
    6:23 1
    7:71
    8:2221
    9:331
    10:25 1

    最后一个数字是将我们在主\u列表中的数字相乘得出的 1*2*3*2*5*7*2*3=2520


    如前所述,Python非常擅长数字。它是这项工作的最佳工具。这就是为什么你应该使用它来代替C、Erlang、Go、D或任何其他动态/静态语言来进行Euler练习的原因。

    我用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;
       }
    
    #包括
    #包括
    int main()
    {
    int i;
    整数计数;
    对于(i=21;i>0;i++)
    {count=0;
    
    对于(int j=2;j只是对上述评论的一些想法

    @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

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

    $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解决

    抱歉,刚刚编辑了这个问题。谢谢,现在更好了,但在下一个循环中,它将再次为零,如果每个数字的剩余部分除以1到20的和等于0,那么在结束循环后,它仍然为零。我做了一些研究,仍然无法找到答案。我是根据你和其他人做的ers的建议!谢谢!(我编辑了问题并解释了我最终是如何做到的)嗯……这有点令人尴尬,但我没有很好的数学背景……如果你能简化基础的话……不要尴尬,许多优秀的程序员都在为数学的更纯粹分支而挣扎。你需要探究这个问题的基本要点是,一个数要被1-20之间的每个数整除,它实际上只需要被I整除1和20之间的素数,即2,3,5,7,11,13,17,19。这是因为1和20之间的每一个数字都可以写成小于或等于自身的素数的乘积。所以取10,你可以写成2*5.15,3*5.16,2*2*2*2。插入另一个注释:那么你要找的数字看起来是这样的:(2^a)*(3^b)*(5^c)*(7^d)*(11^e)*(13^f)*(17^g)*(19^h)。不要被这里的符号吓倒,它只是意味着你需要搜索指数,而不是每个数字。我是根据你和其他人的建议做的!谢谢!(我编辑了问题并解释了我最终是如何做的)
    $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;
            }