Все возможные пифагорейские тройки

Вот вопрос

Найдите все пифагорейские тройки для стороны1, стороны2 и гипотенузы не более 500. Используйте тройную вложенность для циклов, которые пробуют возможности.

Ниже моя попытка

#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++, я изучаю его самостоятельно. И это не домашнее задание, я сформулировал проблему, потому что это лучший способ выразить проблему.

РЕДАКТИРОВАТЬ

Правая сторона сторона1 сторона2

RUN SUCCESSFUL (общее время: 1сек)

РЕДАКТИРОВАТЬ 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;
                 }


            }
        }
    }
}

2 ответа

Решение

Это не бесконечный цикл, это просто очень медленный конечный цикл. Ввод / вывод медленный - вы печатаете 500*500 = 250 000 строк текста в cout оператор в среднем цикле, и вывод 250 000 строк текста на консоль очень, очень медленный. Если вы удалите этот оператор печати, он будет выполняться намного быстрее.

Во-вторых, у вас есть ошибка в вашей логике. Переменные side1, side2, а также rightSide никогда не сбрасывайте в 0 в соответствующее время, поэтому они просто продолжают увеличиваться за пределы их предполагаемых значений. Попробуйте сбросить их до 0 или просто использовать счетчики циклов вместо дополнительных переменных, подобных этому.

Кроме того, из проблем, указанных @Adam Rosenfield. Программа не будет быстро заканчиваться с такими 3 циклами, если предел будет увеличен немного выше.

Первое наблюдение заключается в том, что вам не нужен 3-й внутренний цикл, так как гипотенуза может быть рассчитана и сравнена. Вычислите гипотенузу с двух сторон, превратите ее в целое число и проверьте, сохраняется ли равенство Пифагора.

Вы можете сделать еще несколько замечаний: две стороны являются взаимозаменяемыми, поэтому нам нужно только зациклить до sqrt (500 2/2) (переход на другую сторону просто перевернет стороны). Для 2-го внутреннего цикла для другой стороны прямоугольного треугольника, так как мы знаем верхний предел, мы можем сократить количество циклов, выполнив цикл до sqrt (500 2 - side1 2).

Псевдокод, а не код C (^ в коде C есть XOR, но я использую ^ в псевдокоде ниже для обозначения мощности). round() будет округлять до ближайшего целого числа (вам может потребоваться реализовать это). Верхний предел для 2 циклов может быть кэширован непосредственно перед входом в цикл, так как их значение не изменится во время цикла:

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
        }
    }
}
Другие вопросы по тегам