1

这是问题

找到所有不超过 500 的边 1、边 2 和斜边的毕达哥拉斯三元组。使用三元组嵌套的 for 循环来尝试可能性。

以下是我的尝试

#include <iostream>
#include <iomanip>

using namespace std;

int main()
{
    int side1 = 0;
    int side2 = 0;
    int rightSide = 0;

    cout << "Right Side" << setw(10) << "Side1" << setw(10) << "Side2" << endl;

    for(int i=1;i<=500;i++)
    {
        side1++;
        //cout << side1 << endl;

        for(int a=1;a<=500;a++)
        {
            side2++;
            //cout << "side 2 " << side2 << endl;

            for(int c=1;c<=500;c++)
            {
                rightSide++;
                int rightSideSqr = rightSide*rightSide;
                int side1Sqr = side1*side1;
                int side2Sqr = side2*side2;

                if(rightSideSqr == side1Sqr+side2Sqr)
                {
                    cout << rightSideSqr << setw(15) << side1 << setw(10) << side2 << endl;
                 }


            }
        }
    }
}

但它没有成功,似乎是一个无限循环。请帮忙。

请注意:我是 C++ 新手,我是自学的。而且,这不是作业,我做了问题陈述,因为这是表达问题的最佳方式。

编辑

右侧 Side1 Side2

运行成功(总时间:1s)

编辑 2

工作代码

#include <iostream>
#include <iomanip>

using namespace std;

int main()
{
    //int side1 = 0;
    //int side2 = 0;
    //int rightSide = 0;

    cout << "Right Side" << setw(10) << "Side1" << setw(10) << "Side2" << endl;

    for(int i=1;i<=500;i++)
    {
        //side1++;
        //cout << side1 << endl;

        for(int a=1;a<=500;a++)
        {
            //side2++;
            //cout << "side 2 " << side2 << endl;

            for(int c=1;c<=500;c++)
            {
                //rightSide++;
                int rightSideSqr = c*c;
                int side1Sqr = i*i;
                int side2Sqr = a*a;

                if(rightSideSqr == (side1Sqr+side2Sqr))
                {
                    cout << rightSideSqr << setw(15) << i << setw(10) << a << endl;
                 }


            }
        }
    }
}
4

2 回答 2

3

这不是一个无限循环,它只是一个非常慢的有限循环。I/O 很慢——您在cout中间循环的语句中打印出 500*500 = 250,000 行文本,而将 250,000 行文本打印到控制台非常非常慢。如果您删除该打印语句,它将执行得更快。

其次,你的逻辑有错误。变量side1,side2rightSide永远不会在适当的时候重置为 0,因此它们只会不断增加超出其预期值。尝试将它们重置为 0,或者只使用循环计数器而不是这样的额外变量。

于 2012-09-19T17:45:56.800 回答
1

除了@Adam Rosenfield 指出的问题。如果限制提高一点,程序将无法通过 3 个这样的循环快速完成。

第一个观察是您不需要第三个内循环,因为可以计算和比较斜边。计算两条边的斜边,取整数,检查毕达哥拉斯等式是否仍然成立。

你可以做更多的观察:2 边是可以互换的,所以我们只需要循环到 sqrt(500 2 /2) (过去只会颠倒边)。对于直角三角形另一边的第二个内循环,由于我们知道上限,我们可以通过循环到 sqrt(500 2 - side1 2 ) 来减少循环数。

伪代码,而不是 C 代码^在 C 代码中是 XOR,但我^在下面的伪代码中使用来表示幂)。round()将四舍五入到最接近的整数(您可能需要实现这一点)。两个循环的上限可以在进入循环之前被缓存,因为它们的值在循环期间不会改变:

for (side1 = 1; side1 <= round(sqrt(500^2 / 2)); side1++) {
    for (side2 = side1; side2 <= round(sqrt(500^2 - i^2)); side2++) {
        hypo = round(sqrt(side1^2 + side2^2))

        if (hypo^2 == side1^2 + side2^2) {
           printResult
        }
    }
}
于 2012-09-19T18:01:44.127 回答