寻找毕达哥拉斯三重奏(项目欧拉)

时间:2011-03-15 20:59:50

标签: c++

我很清楚这种蛮力方法很糟糕,我应该使用欧几里德公式之类的东西,并且不需要最终循环,因为c = 1000 - (a + b)等......但是现在我只想让它发挥作用。

bool isPythagorean(int a, int b, int c) {
    if((a*a + b*b) == c*c && a < b && b < c) {
        cout << a << " " << b << " " << c << endl;
        return true;
    } else {
        return false;
    }
}

int main()
{
    int a = 1;
    int b = 2;
    int c = 3;

    for(a = 1; a < b; ++a) {
        for(b = 2; b < c; ++b) {
            for(c = 3; a + b + c != 1000 && !isPythagorean(a, b, c); ++c) {
            }
        }
    }

    return 0;
}

在大多数情况下,代码按照我的预期运行。我无法弄清楚为什么它会因为+ b + c = 1000而害羞。

我的最后三联体是280 < 294&lt; 406,总计980。

如果我删除a&lt; b&lt; c检查,三联体变为332,249,415,总计996。

所有结果都符合毕达哥拉斯定理 - 我无法降低a + b + c = 1000。

什么阻止了我?

3 个答案:

答案 0 :(得分:5)

这部分代码非常奇怪地迭代:

for(a = 1; a < b; ++a) {
    for(b = 2; b < c; ++b) {
        for(c = 3; a + b + c != 1000 && !isPythagorean(a, b, c); ++c) {
        }
    }
}

最初,a = 1, b = 2, c = 3。但是在第一个for(c)c=997时,for(b)的第二次迭代将最多b=996。继续这样做,在某些时候你会发现一个三(a,b,c),此时,c可能不接近1000,b将迭代到c所处的状态......所以上。我认为你不能准确预测它会产生三元组的方式。

我建议你选择像

这样的东西
for(a = 1; 3*a < 1000; ++a) {
    for(b = a+1; a+2*b < 1000; ++b) {
        for(c = b+1; a + b + c != 1000 && !isPythagorean(a, b, c); ++c) {
        }
    }
}

这样,循环将不依赖于先前找到的三元组。

......你真的应该使用Euclid的方法。

答案 1 :(得分:1)

最内层for循环中的条件明确表示永远不会测试a + b + c等于1000的任何内容。您的意思是a + b + c <= 1000吗?

答案 2 :(得分:0)

备选可能的解决方案:

#include <iostream>
#define S(x) x*x

int main() {
int c = 0;
for(int a=1;a<(1000/3);++a) {
    // a < b; so b is at-least a+1 
    // If a < b < c and a + b + c = 1000 then 'a' can't be greater than 1000/3  
    // 'b' can't be greater than 1000/2. 
    for(int b=a+1;b<(1000/2);++b) {         
        c = (1000 - a - b); // problem condition
        if(S(c) == (S(a) + S(b) ))
            std::cout<<a*b*c;
        }
    }       
return 0;
}

有关其他参考,请参阅以下帖子 Finding Pythagorean Triples: Euclid's Formula Generating unique, ordered Pythagorean triplets