2012-03-31 70 views
1

我在項目歐拉工作problem 9查找勾股數:歐幾里德式

存在着只有一個勾股數爲其中+ B + C = 1000 查找產品ABC。

我寫的以下代碼使用歐幾里德公式來生成素數。出於某種原因,我的代碼返回「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; 
} 

並且還,有沒有更好的方式來打破多重循環,而無需使用「破發」,或者是「破」最佳?


下面是更新後的代碼,只有改變:

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」作爲一個答案)。我知道,很多括號。

+0

有你什麼特別的原因使用(有點令人困惑的)'i','ii'和'iii'變量而不是直接使用'm','n'和'k'作爲循環變量? – Taymon 2012-03-31 02:59:27

+1

1)'m + n'應該是奇數,2)'m> n' 3)'m'和'n'是coprimes。 :\先檢查這些。 :| – st0le 2012-03-31 03:10:24

+0

沒有理由,除了迷惑自己...修正了編輯。 – 2012-03-31 03:42:07

回答

2

新的問題是,解決方案發生在k = 1,所以在2開始你的k直接錯過了答案。

而不是通過不同的k值循環,你可以檢查當前的總和平均分1000。這裏就是我的意思(使用討論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; 

我也切換兩個周圍循環,這樣就可以只初始化米爲更大的n比,而不是檢查每個迭代。

請注意,這個新方法,解決沒有對於k發生= 1(在如何環路運行得有差別,這是沒有問題的)

2

推測sum應該是a + b + c。然而,你的代碼中沒有任何地方可以做到這一點,這可能是你的問題。

要回答最後一個問題:是的,您可以使用goto。突破多個嵌套循環是非常罕見的情況之一,因爲它不被認爲是有害的。

+0

謝謝!我真的很害怕這樣做,因爲使用'goto'有很多。 – 2012-03-31 02:59:01

+0

想通了第一部分,看修改後的答案。 – Taymon 2012-03-31 03:03:31

+0

嘿,我真的很聰明。當我拿出一些東西去調試時,我討厭它,只是忘記了以後才放它。 – 2012-03-31 03:11:06