|
Компьютерный форум OSzone.net » Программирование, базы данных и автоматизация действий » Программирование и базы данных » C/C++ - Помогите с задачей по Тройкам Пифагора |
|
|
C/C++ - Помогите с задачей по Тройкам Пифагора
|
Новый участник Сообщения: 25 |
Профиль | Отправить PM | Цитировать Задание:
Если p - периметр прямоугольного треугольника со сторонами {a, b, c}, то есть ровно три целочисленных решения для p = 120:{20, 48, 52}, {24, 45, 51}, {30, 40, 50} Для какого значения p<1000 число решений максимально? Буду безмерно благодарен тем, кто сможет помочь, готов даже премировать Если что, ася 443-478 |
|
Отправлено: 21:19, 25-11-2008 |
Ветеран Сообщения: 3320
|
Профиль | Отправить PM | Цитировать quaker_strelok в чём сложность в математической части или/и в части реализации?
В задании прямоугольный треугольник, это ж хрестоматийный случай по теореме Пифагора: Квадрат одной из сторон равен сумме квадратов других сторон. http://ru.wikipedia.org/wiki/Теорема_Пифагора Надеюсь теперь с математикой ясность. Теперь насчёт реализации. Если сильно напрягаться не хочется, пускай проц напрягается, можно задействовать банальный перебор, с помощью циклов. #include <stdio.h> int main(int argc, char* argv[]) { int p, pMax=0; for (p=1;p<1000;p++) { //p=120; printf("\nCurrent p=%i ",p); for (int a=1; a<p; a++) for (int b=1; b<p; b++) for (int c=1; c<p; c++) //if (p==(a + b + c) && a < (b + c) && b < (c + a) && c < (a + b)) if (p==(a + b + c) && (a*a == (b*b + c*c) || b*b == (c*c + a*a) || c*c == (a*a + b*b))) { printf("{a=%i b=%i c=%i} ",a,b,c); pMax=p; } } printf("p max = %i",pMax); return 0; } Для p<1000 ответ будет таков Цитата:
|
|
Последний раз редактировалось Admiral, 26-11-2008 в 02:31. Отправлено: 01:35, 26-11-2008 | #2 |
Для отключения данного рекламного блока вам необходимо зарегистрироваться или войти с учетной записью социальной сети. Если же вы забыли свой пароль на форуме, то воспользуйтесь данной ссылкой для восстановления пароля. |
Новый участник Сообщения: 25
|
Профиль | Отправить PM | Цитировать Спасибо огромное, проблема у меня как раз в реализации, т.к. только начал изучать C++, но прога и впрямь долгая.. боюсь на компах в инсте она пол дня будет считаться...
1) Вы не уловили самого вопроса.. надо не максимальный периметр, при котором есть решения, а при каком периметре число решений максимально 2) if (p==(a + b + c) && a < (b + c) && b < (c + a) && c < (a + b)) в чем смысл этой строчки? 3) везде в циклах: for (int a=1; a<p; a++) for (int b=1; b<p; b++) for (int c=1; c<p; c++) для быстроты подсчета можно заменить p на p/2, т.к. сторона треугольника никогда не может быть больше полупериметра.. я прав? |
Отправлено: 17:28, 26-11-2008 | #3 |
Ветеран Сообщения: 3320
|
Профиль | Отправить PM | Цитировать Сразу скажу, что код выполнен на С, из того что можно отнести лишь к С++ только удобный однострочный комментарий \\ вместо многострочного Сишного \* */.
По моим наблюдениям скорость проца не сильно влияет на настолько не оптимизированную программу. В данном случаи строчка Current p развлекает скучающего оператора ПК, но если с графикой в С знакомство есть то можно строить треугольники по текущим данным. 1)Да есть немного. Надеюсь результаты решения (какие возможные значения a b c на данный периметер) сохранять не нужно? 2) А это я сразу не уловил, что речь идёт про частный случай - прямоугольный треугольник, а не про треугольник в общем. Это условие не вырождение треугольника (другими словами, при таких условиях можно нарисовать треугольник). Я указал ниже в комментарии к коду, что данная строчка закомментирована. Это на тот случай, если кому-то понадобится про треугольник в общем случаи. 3)Да это так, любая из сторон треугольника всегда меньше полупериметра. Вот и первые шаги в оптимизации. Какая может быть нижняя граница для циклов? При заданном периметре, меньше чего не может быть наименьшая сторона прямоугольного треугольника? Это те вопросы, на которые не обходимо ответить, что б оптимизировать код. Касательно уточнённого задания, то каркас отлова необходимых значений данн, осталось добавить двух мерный массив для отлова: 1) значений периметров, 2) количество решений с ними, 3)сортировка и вывод наибольшего по количеству решений периметра. Без третьего пункта, примерно что-то на подобии такого |
Последний раз редактировалось Admiral, 27-11-2008 в 03:43. Причина: поправил код Отправлено: 01:26, 27-11-2008 | #4 |
Новый участник Сообщения: 25
|
Профиль | Отправить PM | Цитировать Спасибо еще раз
куда вставить код, который вы привели? выложите полный код, если можно |
|
Отправлено: 01:33, 27-11-2008 | #5 |
Ветеран Сообщения: 3320
|
Профиль | Отправить PM | Цитировать Внимание! Код не делает выборку совпадений значений сторон, но в разной последовательности, например для p=384 варианты {a=96 b=128 c=160} и {a=128 b=96 c=160} считаются абсолютно разными. Поскольку это происходит для всех p без исключения, то решение будет найденное корректно.
/*Если p - периметр прямоугольного треугольника со сторонами {a, b, c}, то есть ровно три целочисленных решения для p = 120:{20, 48, 52}, {24, 45, 51}, {30, 40, 50} Для какого значения p<1000 число решений максимально?*/ #include <stdio.h> int main(int argc, char* argv[]) { const int MyLimit = 1000; int p, a, b, c, i=0, pMaxRes[MyLimit][2]; for (p=3; p<MyLimit; p++) { printf("\nCurrent p=%i ",p); for (a=1; a<p/2; a++) for (b=1; b<p/2; b++) for (c=1; c<p/2; c++) if (p==(a + b + c) && c*c == (a*a + b*b)) { printf("{a=%i b=%i c=%i} ", a, b, c); if (i==0) { pMaxRes[i][0]=p; pMaxRes[i][1]=1; i++; } else { if (p!=pMaxRes[i-1][0]) { pMaxRes[i][0]=p; pMaxRes[i][1]=1; i++; } else pMaxRes[i-1][1]++; } } } for (a=0; a<i; a++) printf("\nValid perimeter = %i match %i", pMaxRes[a][0], pMaxRes[a][1]); return 0; } Как видно из таблицы Valid perimeter = 840 match 16 - ответ, то есть 840 максимальный целочисленный периметр, меньший за 1000, прямоугольного треугольника, при котором число решений максимально и составляет 16, с учётом того что треугольник можно разворачивать. Если нужен результат чётко, то нужно поработать с двухмерным массивом pMaxRes[][]: отсортировать/найти наибольший элемент во втором ряде и вывести соответствующиё значение с первого. |
Последний раз редактировалось Admiral, 27-11-2008 в 02:40. Отправлено: 02:06, 27-11-2008 | #6 |
Новый участник Сообщения: 25
|
Профиль | Отправить PM | Цитировать у меня последний код не выполняется...
1) по моему где-то лишняя скобочка.... 2) пишет что вот здесь printf("p max = %i",pMax); error C2065: 'pMax' : undeclared identifie |
Отправлено: 19:03, 27-11-2008 | #7 |
Будем жить, Маэстро... Сообщения: 6694
|
Профиль | Сайт | Отправить PM | Цитировать Цитата quaker_strelok:
Цитата quaker_strelok:
Выделите текст внутри кода, что написал Admiral, - скопируйте - вставьте в файл .cpp - сохраните, откройте и откомпилируйте. |
||
------- Отправлено: 19:13, 27-11-2008 | #8 |
Новый участник Сообщения: 25
|
Профиль | Отправить PM | Цитировать Drongo, опс, действительно ошибка получилась у меня.. прошу прощения.
Цитата Admiral:
|
|
Отправлено: 00:10, 28-11-2008 | #9 |
Ветеран Сообщения: 3320
|
Профиль | Отправить PM | Цитировать quaker_strelok - после уточнение задания на смену переменной pMax пришёл массив pMaxRes[][], впрочем можно было завести несколько переменных, но с массивом нагляднее.
Что б не повторять весь код заново приведу окончание программы |
Отправлено: 21:52, 28-11-2008 | #10 |
|
Участник сейчас на форуме | Участник вне форума | Автор темы | Сообщение прикреплено |
| |||||
Название темы | Автор | Информация о форуме | Ответов | Последнее сообщение | |
C/C++ - помогите с задачей по СИ!!! | feliks2009 | Программирование и базы данных | 4 | 16-11-2009 00:18 | |
Delphi - [решено] Помогите с задачей /Pascal/ | Habetdin | Программирование и базы данных | 23 | 11-11-2009 22:46 | |
C/C++ - [решено] Помогите с задачей! | FeuerEngel | Программирование и базы данных | 3 | 28-05-2009 09:58 | |
VBS/WSH/JS - Помощь с простенькой задачей) | Triz | Программирование и базы данных | 10 | 05-03-2009 18:35 | |
Delphi - [решено] Помогите с комбинаторной задачей! | ALI | Программирование и базы данных | 16 | 01-01-2009 14:10 |
|