寻找毕达哥拉斯三重奏:欧几里德的公式

时间:2012-03-31 02:48:26

标签: c++

我正在使用Project Euler中的problem 9

  

恰好存在一个毕达哥拉斯三重态,其中a + b + c = 1000。   找到产品abc。

我编写的以下代码使用Euclid的公式来生成素数。出于某种原因,我的代码返回“0”作为答案;即使变量值对于前几个循环是正确的。由于问题非常简单,代码的某些部分并未完美优化;我认为这不重要。代码如下:

#include <iostream>
using namespace std;

int main()
{
    int placeholder;    //for cin at the end so console stays open
    int a, b, c, m, n, k;
    a = 0;  b = 0;  c = 0;
    m = 0;  n = 0;  k = 0;  //to prevent initialization warnings
    int sum = 0;
    int product = 0;

    /*We will use Euclid's (or Euler's?) formula for generating primitive
     *Pythagorean triples (a^2 + b^2 = c^2): For any "m" and "n",
     *a = m^2 - n^2 ; b = 2mn ; c = m^2 + n^2 . We will then cycle through
     *values of a scalar/constant "k", to make sure we didn't miss anything.
     */

    //these following loops will increment m, n, and k,
    //and see if a+b+c is 1000. If so, all loops will break.
    for (int iii = 1; m < 1000; iii++)
    {
        m = iii;
        for (int ii = 1; n < 1000; ii++)
        {
            n = ii;
            for (int i = 1; k <=1000; i++)
            {
                sum = 0;
                k = i;
                a = (m*m - n*n)*k;
                b = (2*m*n)*k;
                c = (m*m + n*n)*k;
                if (sum == 1000) break;
            }
            if (sum == 1000) break;
        }
        if (sum == 1000) break;
    }
    product = a * b * c;

    cout << "The product abc of the Pythagorean triplet for which a+b+c = 1000 is:\n";
    cout << product << endl;
    cin >> placeholder;
    return 0;
}

而且,有没有更好的方法来突破多个循环而不使用“break”,或者是“break”最优?


这是更新的代码,只有更改:

for (m = 2; m < 1000; m++)
    {
        for (int n = 2; n < 1000; n++)
        {
            for (k = 2; (k < 1000) && (m > n); k++)
            {
                sum = 0;
                a = (m*m - n*n)*k;
                b = (2*m*n)*k;
                c = (m*m + n*n)*k;
                sum = a + b + c;
                if ((sum == 1000) && (!(k==0))) break;
            }

它仍然不起作用(现在给出“1621787660”作为答案)。我知道,很多括号。

2 个答案:

答案 0 :(得分:2)

据推测,sum应该是a + b + c。但是,你的代码中没有任何地方可以实际执行此操作,这可能是你的问题。

回答最后一个问题:是的,您可以使用goto。打破多个嵌套循环是一种罕见的不被认为有害的情况。

答案 1 :(得分:2)

新问题是k = 1解决方案出现了,所以从2开始你的k会完全错过答案。

您可以检查当前总和何时均匀分配1000,而不是循环显示不同的k值。这就是我的意思(使用讨论过的goto语句):

      for (n = 2; n < 1000; n++)
        {
          for (m = n + 1; m < 1000; m++)
            {
              sum = 0;
              a = (m*m - n*n);
              b = (2*m*n);
              c = (m*m + n*n);
              sum = a + b + c;
              if(1000 % sum == 0)
                {
                  int k = 1000 / sum;
                  a *= k;
                  b *= k;
                  c *= k;
                  goto done;
                }
            }
        }
     done:
      product = a * b * c;

我还切换了两个for循环,这样你就可以将m初始化为大于n而不是检查每次迭代。

请注意,使用这种新方法,k = 1时不会出现解决方案(只是循环运行的方式不同,这不是问题)