Warning: file_get_contents(/data/phpspider/zhask/data//catemap/4/algorithm/12.json): failed to open stream: No such file or directory in /data/phpspider/zhask/libs/function.php on line 167

Warning: Invalid argument supplied for foreach() in /data/phpspider/zhask/libs/tag.function.php on line 1116

Notice: Undefined index: in /data/phpspider/zhask/libs/function.php on line 180

Warning: array_chunk() expects parameter 1 to be array, null given in /data/phpspider/zhask/libs/function.php on line 181
Algorithm 将给定的数字表示为四个平方和_Algorithm_Math - Fatal编程技术网

Algorithm 将给定的数字表示为四个平方和

Algorithm 将给定的数字表示为四个平方和,algorithm,math,Algorithm,Math,我正在寻找一种算法,它将给定的数字表示为(最多)四个平方的和 例子 120=82+62+42+22 6=02+12+12+22 20=42+22+02+02 我的方法 取平方根,对剩余部分重复此操作: while (count != 4) { root = (int) Math.sqrt(N) N -= root * root count++ } 但当N为23时,即使有一个解决方案,也会失败: 32+32+22+12 问题: 有没有其他算法可以做到这一点 这总是可能

我正在寻找一种算法,它将给定的数字表示为(最多)四个平方的和

例子 120=82+62+42+22
6=02+12+12+22
20=42+22+02+02

我的方法 取平方根,对剩余部分重复此操作:

while (count != 4) {
    root = (int) Math.sqrt(N)
    N -= root * root
    count++
} 
但当N为23时,即使有一个解决方案,也会失败:

32+32+22+12

问题:
  • 有没有其他算法可以做到这一点

  • 这总是可能的吗


  • 这是一个简单的
    4
    循环的解决方案

    max = square_root(N)
    for(int i=0;i<=max;i++)
      for(int j=0;j<=max;j++)
         for(int k=0;k<=max;k++)
              for(int l=0;l<=max;l++)
                  if(i*i+j*j+k*k+l*l==N){
                            found
                           break;
                    }
    
    max=平方根(N)
    对于(inti=0;i它总是可能的——这是数论中的一个定理,叫做“拉格朗日四平方定理”

    为了有效地解决这一问题,本文给出了一种在预期O((logn)^2)时间内运行的方法

    这里有关于实施的有趣讨论:

    通过找到。

    是否始终可行? 是的,缔约国指出:

    每个自然数都可以表示为四个整数平方的和

    这已经在几个方面得到了证明

    算法 有一些更智能的算法,但我建议使用以下算法:

    将数字分解为素数因子。它们不必是素数,但越小越好:因此素数是最好的。然后按如下所示解决这些因子中的每一个的任务,并将得到的任何4个平方与之前找到的4个平方和组合在一起

    (a2+b2+c2+d2) (A2+B2+C2+D2)=
    (aA+bB+cC+dD)2+
    (aB)− bA+cD− dC)2+
    (aC)− 屋宇署− 钙+分贝)2+
    (公元前+公元前− cB− dA)2

  • 给定一个数字n(上述因素之一),得到不大于n的最大平方,然后查看n减去该平方是否可以写成三个平方的和,使用:这是可能的,当且仅当该数字不是以下形式时:

    4a(8b+7)

    如果这个方块不合适,试试下一个较小的方块,直到你找到一个为止。它保证会有一个方块,而且大多数方块都会在几次重试后找到

  • 尝试以与步骤1相同的方式找到一个实际的第二个平方项,但现在测试其可行性,扩展使用它意味着:

    如果n与3模4全等的素因子都是偶数指数,那么n可以表示为两个平方和,反之亦然

    如果这个正方形不合适,试试下一个较小的,直到你找到为止。保证会有一个

  • 现在我们减去两个平方后有一个余数。试着减去第三个平方,直到得到另一个平方,这意味着我们有一个解决方案。这一步可以通过首先分解最大的平方因子来改进。然后当两个平方项被识别时,每个平方项可以再次乘以该平方的平方根除数

  • 这大致就是这个想法。为了找到主要因素,有以下几种。下面我将使用

    这是JavaScript代码,因此您可以立即运行它--它将生成一个随机数作为输入,并显示为四个平方和:

    函数除数(n,因子){
    var除数=1;
    而(n%系数==0){
    n=n/系数;
    除数=除数*因子;
    }
    返回除数;
    }
    函数getPrimesUntil(n){
    //素筛算法
    变量范围=数学地板(数学sqrt(n))+1;
    var isPrime=数组(n).填充(1);
    var素数=[2];
    对于(var m=3;m0;sq1--){
    n2=n1-sq1*sq1;
    //一个数字可以写成三个平方和
    //它不是表4^a(8b+7)
    如果((n2/除数(n2,4))%8!==7)中断;//发现了一种可能性
    }
    //2.找到合适的第二个正方形
    对于(sq2=数学地板(数学sqrt(n2));sq2>0;sq2--){
    n3=n2-sq2*sq2;
    //一个数字可以写成两个平方和
    //其形式为4a+3的所有素因子都具有偶数指数
    factors3=素数。因式分解(n3);
    ok=正确;
    对于(系数3中的f3){
    ok=(f3.value%4!=3)| |(f3.count%2==0);
    如果(!ok)中断;
    }
    如果(ok)中断;
    }
    //要节省时间,请从以前的因式分解中提取最大的平方因子:
    sq=1;
    对于(系数3中的f3){
    sq*=数学功率(f3.value,(f3.count-f3.count%2)/2);
    f3.count=f3.count%2;
    }
    n3/=sq*sq;
    //3.找一个合适的第三方
    sq4=0;
    //b.找到剩余值的平方:
    对于(sq3=数学地板(数学sqrt(n3));sq3>0;sq3--){
    n4=n3-sq3*sq3;
    //看看这是否会产生两个平方和:
    sq4=数学地板(数学sqrt(n4));
    如果(n4==sq4*sq4)中断;//是!
    }
    //将平方除数合并回步骤3的结果中:
    sq3*=sq;
    sq4*=sq;
    //4.将这四个正方形与之前的任何四个正方形合并
    //使用Euler平方恒等式,我们得到了四倍:
    而(f.count--){
    [res1,res2,res3,res4]=[
    Math.abs(res1*sq1+res2*sq2+res3*sq3+res4*sq4),
    Math.abs(res1*sq2-res2*sq1+res3*sq4-res4*sq3),
    Math.abs(res1*sq3-res2*sq4-res3*sq1+res4*sq2),
    Math.abs(res1*sq4+res2*sq3-res3*sq2-res4*sq1)
    ];
    }
    }
    //按降序返回4个方块(为方便起见):
    返回[r]