Бумер Опубликовано 26 сентября, 2006 Жалоба Поделиться Опубликовано 26 сентября, 2006 Привет, народ. Вот в универе по 3-ей Лабе мне надо решить задачу: Если три данных числа могут являться сторонами остроугольного треугольника, то найти его площадь и наименьший острый угол. Само решение понятно, но есть один вопрос, да и хотелось бы, чтобы вы проверили мое решение и дали советы – может можно как нибудь лучше решить. Сначала выясним, могут ли эти длины (а, b, c) являться сторонами треугольника. Для того, чтобы они являлись таковыми, необходимо, чтобы a+b>c and b+c>a and a+c>b. Теперь найдем углы по теореме косинусов: c*c=a*a+b*b-2*a*b*cos(c1), где с1 –угол против стороны с Получим: C1=arccos((a*a+b*b-c*c)/2*a*b) Аналогично A1=arccos((b*b+c*c-a*a)/2*b*c) B1=arccos((a*a+c*c-b*b)/2*a*c) Площадь треугольника будет равна: S=sqrt(p(p-a)(p-b)(p-c)), где р – полупериметр Ну угол наименьший я собираюсь найти сравнением С1 с А1, затем меньшее сравнить с В1. Код напишу завтра. Ну как вам мое решение? Единственный вопрос – как в паскале вычислять арксинус, арккосинус?????? Ссылка на комментарий Поделиться на другие сайты Поделиться
Тролль Опубликовано 26 сентября, 2006 Жалоба Поделиться Опубликовано 26 сентября, 2006 Бумер: О вычислении в Паскале арксинуса и арккосинуса: эти функции не были введены Виртом, так как арксинус легко выражается через арктангенс, который в Паскале есть, а арккосинус - через арксинус. Конкретно, arcsin x = arctg x/(√(1-x²)), а arccos x = π/2 - arcsin x Выведенные формулы у тебя записаны неточно. Наводящий вопрос: сколько будет 2/2*2 ? Если правильно запишешь, все должно получиться :) . Ссылка на комментарий Поделиться на другие сайты Поделиться
Бумер Опубликовано 29 сентября, 2006 Автор Жалоба Поделиться Опубликовано 29 сентября, 2006 program lab_3;vara,b,c,a1,b1,c1,x1,x2,x3,s,min_ug,p: real;beginwrite ('wwedite a,b,c');read (a,b,c);if ((a+b)>c) and ((a+c)>b) and ((b+c)>a) then writeln ('eti chisla mogut bit storonami treugolnika') else writeln ('eti chisla ne mogut bit storonami treugolnika');x1:=(a*a+b*b-c*c)/(2*a*b);c1:=(Pi/2)-arctan(x1/(sqrt(1-(x1*x1))));x2:=(b*b*+c*c-a*a)/(2*b*c);a1:=(Pi/2)-arctan(x2/(sqrt(1-(x2*x2))));x3:=(a*a+c*c-b*b)/(2*a*c);b1:=(Pi/2)-arctan(x3/(sqrt(1-(x3*x3))));min_ug:=0;if a1<b1 then min_ug:=a1 else min_ug:=b1;if min_ug>c1 then min_ug:=c1 else writeln ('minimalnii ugol w treugolnike rawen',min_ug,' radian');p:=(a+b+c)/2;s:=sqrt(p*(p-a)*(p-b)*(p-c));writeln ('ploschad S=',s);end. Вот, написал код - Паскаль вроде не ругается. Только еще есть вопросы: 1. Как перевести угол в градусы из радиан? 2. Что надо писать в коде, если требуется такое: Если (if) условие , то (then) какое нибудь действие пишем, иначе (else) а если это условие не выполняется, то надо продолжать выполнение программы не меняя значений переменных и не выводя ничего на экран, то как это записать. И как такое же записать, но если условие выполняется то надо ничего не делать (продолжить дальше выполнять программу), а если иначе (не выполняется условие), то какое-то действие. То как записывать это "ничего не делать" (имеется в виду продолжение выполнения программы) Желательно с примерами. Заранее спасибо. Кстати, на защите преподша у меня спросила: " К какому типу относится логический тип" Я ей и объяснил: К ЛОГИЧЕСКОМУ типу он и относится. ОНа сказала, что подготавливайся - на следующем занятии будешь еще пытаться защитить лабу номер два. В лекции я потом прочитал, что она диктовала "Логический тип (целый)" Так это ее выдумки или в реале так? НИ в какой книжке подобного я не нашел... Ссылка на комментарий Поделиться на другие сайты Поделиться
Тролль Опубликовано 29 сентября, 2006 Жалоба Поделиться Опубликовано 29 сентября, 2006 (изменено) Бумер: Пример у тебя написан почти правильно. То, что Паскаль не ругается, значит не очень много - только то, что нет синтаксических ошибок. А большинство ошибок обычно семантические, то есть ошибки в логике программы. Высший судья, как всегда, тест на нескольких примерах, чтобы проверить разные разветвления в условных операторах, а при просмотре текста программы часто чего-то и не заметишь. Во всяком случае, видно, что у тебя даже если в начале выполнения программы будет установлено, что треугольника не может существовать, все равно дальнейшие вычисления выполняются и липовые результаты (или ошибки) выдаются. Кроме того, оператор if min_ug>c1 then min_ug:=c1 else writeln ('minimalnii ugol w treugolnike rawen',min_ug,' radian'); выдаст сообщение только если c1 - не минимальный угол, а если он минимальный, то программа ничего не выдаст. Правильно было бы, например, так: if min_ug>c1 then min_ug:=c1; writeln ('minimalnii ugol w treugolnike rawen',min_ug,' radian'); А строка min_ug:=0; не нужна, какой-нибудь угол все равно будет минимальным. Кое-какие скобки у тебя излишни, например, c1:=(Pi/2)-arctan(x1/(sqrt(1-(x1*x1)))); можно проще записать как c1:=Pi/2-arctan(x1/sqrt(1-x1*x1)); Кроме того, на будущее старайся вместо read использовать readln, избежишь возможных ошибок при нескольких операторах чтения. По вопросам. 1: GrToRad:=Pi/180; Angle:=Angle*GrToRad; Можно записать это и одним оператором, но часто переводной коэффициент бывает нужен в нескольких местах программы. 2: if ... then ...; ........; Если тут условие не выполняется, то оператор после then (у меня он обозначен как ... ) тоже выполняться не будет и программа просто пойдет дальше. Для второго случая есть три варианта: а) ........; if ... then else ...; ........; Тут, как говорят, после then стоит пустой оператор, то есть ничего. Синтаксис Паскаля, да и всех других языков, допускает пустые операторы. б) красивее будет так: ........; if NOT(...) then ...; ........; в) еще красивее - просто переписать условие наоборот, например, вместо if NOT(a>b) then ... можно написать if a<=b then ... Этот же пример в записи по варианту а выглядел бы как if a>b then else ... Логический тип - НЕ целый, обозначается он BOOLEAN, но поскольку принимает лабы преподавательница у тебя, а не ты у нее, то тебе придется на время сдачи лаба с ней согласиться. Прочитай басню о волке и ягненке Крылова. Возможно, преподавательница имела в виду, что в Паскале в машинном представлении обычно true представляется как 1, а false как 0, но это совершенно необязательно, а арифметические операции к логическому типу, в отличие от целого, неприменимы. P.S. Да, пока отвечал, забыл твой вопрос - он был относительно перевода в градусы из радианов, а я ответил о переводе градусов в радианы. Впрочем, это делается почти так же: GrToRad:=Pi/180; Angle:=Angle/GrToRad; Или можно так: RadToGr:=180/Pi; Angle:=Angle*RadToGr; Изменено 30 сентября, 2006 пользователем Тролль Ссылка на комментарий Поделиться на другие сайты Поделиться
Бумер Опубликовано 30 сентября, 2006 Автор Жалоба Поделиться Опубликовано 30 сентября, 2006 Во - первых, спасибо, что помогаешь мне! Во вторых: Если я окомпилирую программу, то если числа не могут быть сторонами треугольника программа просто выводит, что числа не могут быть сторонами и завершает работу. А как сделать по правильному. По-моему надо делать точки перехода или метки. Пожалуйста, дай ссылку на такую инфу или сам напиши. Вот я переработал немного код: program lab_3;vara,b,c,a1,b1,c1,x1,x2,x3,s,min_ug, min_ug_grad,p: real;beginwrite ('wwedite a,b,c');readln (a,b,c);if ((a+b)>c) and ((a+c)>b) and ((b+c)>a) then writeln ('Eti chisla mogut bit storonami treugolnika! Wichislit minimalnii ugol i ploschad etogo treugolnika?') else writeln ('Eti chisla ne mogut bit storonami treugolnika');readln;x1:=(a*a+b*b-c*c)/(2*a*b);c1:=(Pi/2)-arctan(x1/(sqrt(1-(x1*x1))));x2:=(b*b*+c*c-a*a)/(2*b*c);a1:=(Pi/2)-arctan(x2/(sqrt(1-(x2*x2))));x3:=(a*a+c*c-b*b)/(2*a*c);b1:=(Pi/2)-arctan(x3/(sqrt(1-(x3*x3)))); if a1<b1 then min_ug:=a1 else min_ug:=b1;if min_ug>c1 then min_ug:=c1;min_ug_grad:=(180/Pi)*min_ug;writeln ('Minimalnii ugol w treugolnike rawen',min_ug,'radian ili',min_ug_grad,'gradusow');p:=(a+b+c)/2;s:=sqrt(p*(p-a)*(p-b)*(p-c));writeln ('ploschad S=',s);readln;end. Ссылка на комментарий Поделиться на другие сайты Поделиться
Тролль Опубликовано 30 сентября, 2006 Жалоба Поделиться Опубликовано 30 сентября, 2006 Бумер: Программа сейчас вообще не может посчитать что-нибудь правильно, поскольку в операторе x2:=(b*b*+c*c-a*a)/(2*b*c); семантическая ошибка, которую я сначала не заметил. Например, введи стороны 3 4 5, и ты увидишь, что программа не выдает никаких результатов. То же будет, если треугольника не получается - программа все равно продолжает вычисления, корень получается из отрицательного числа, вычислить его программа не может и заканчивает выполнение, в отладочном режиме с сообщением об ошибке, а в скомпилированном варианте просто закончит работу. Естественно, это ненормальный выход из программы. Ошибку в этом операторе ты легко найдешь сам. Если подправить оператор, остается придумать, как нормально закончить работу программы, если треугольника не существует. Тут есть три варианта: или перейти оператором goto на конец программы, но использование оператора goto в Паскале считается плохим стилем программирования, или поставить всю оставшуюся часть программы внутрь условного оператора, используя begin ... end, или - самый правильный способ - завершить выполнение программы вызовом специально предусмотренной для этого процедуры exit. Кстати, в программе вопрос Eti chisla mogut bit storonami treugolnika! Wichislit minimalnii ugol i ploschad etogo treugolnika? чисто риторический, никаких вариантов ответа на него не предлагается. Его лучше вообще исключить, так в нем нет никакого смысла. Тогда эта часть программы будет выглядеть так: if ((a+b)>c) and ((a+c)>b) and ((b+c)>a) then writeln ('Eti chisla mogut bit storonami treugolnika!') else begin writeln ('Eti chisla ne mogut bit storonami treugolnika! Dlja vihoda nazhmite Enter'); readln; exit end; Ну и кое-какие косметические улучшения: вместо write ('wwedite a,b,c'); я бы написал writeln ('wwedite a,b,c, razdeljaja chisla probelami'); а вывод величин угла и площади оформил не в экспоненциальной форме записи, а в обычной, то есть как writeln ('Minimalnii ugol w treugolnike rawen ',min_ug:4:2,' radian ili ',min_ug_grad:6:2,' gradusow'); и writeln ('ploschad S=',s:10:2); Ссылка на комментарий Поделиться на другие сайты Поделиться
Feur_GOR Опубликовано 30 сентября, 2006 Жалоба Поделиться Опубликовано 30 сентября, 2006 (изменено) вместо write ('wwedite a,b,c'); я бы написал writeln ('wwedite a,b,c, razdeljaja chisla probelami'); А может так: writeln('Введите сторону а'); readln(a); writeln('Введите сторону а'); readln(b); writeln('Введите сторону а'); readln©; Кстати, в Паскале язык переключается на русский:правый шифт+левый контрол, а на буржуйский левый шифт+правый контрол... Изменено 30 сентября, 2006 пользователем Feur_GOR Ссылка на комментарий Поделиться на другие сайты Поделиться
Тролль Опубликовано 1 октября, 2006 Жалоба Поделиться Опубликовано 1 октября, 2006 Бумер: Кстати, на защите преподша у меня спросила: " К какому типу относится логический тип" Я ей и объяснил: К ЛОГИЧЕСКОМУ типу он и относится. ОНа сказала, что подготавливайся - на следующем занятии будешь еще пытаться защитить лабу номер два. В лекции я потом прочитал, что она диктовала "Логический тип (целый)" Так это ее выдумки или в реале так?Да, еще относительно логического типа: логический тип - НЕ целый, но к какому типу он относится, сказать можно. Логический тип является одним из встроенных порядковых простых типов. Целый тип, кстати, тоже относится к этому семейству. Иногда простые типы иначе называют скалярными, а встроенные - стандартными, но скорее всего, преподавательницу интересовало слово "порядковый". Ссылка на комментарий Поделиться на другие сайты Поделиться
Бумер Опубликовано 4 октября, 2006 Автор Жалоба Поделиться Опубликовано 4 октября, 2006 x2:=(b*b*+c*c-a*a)/(2*b*c); По поему здесь семантич. ошибки нет. какая здесь может быть ошибка? А вот в c1:=(Pi/2)-arctan(x1/(sqrt(1-(x1*x1)))); Корень можно извлекать только из неотрицат. числа. А как это записать (что должна прога выводить, если подкоренное выражение меньше нуля?) Ссылка на комментарий Поделиться на другие сайты Поделиться
Тролль Опубликовано 4 октября, 2006 Жалоба Поделиться Опубликовано 4 октября, 2006 (изменено) Бумер: По поему здесь семантич. ошибки нет. какая здесь может быть ошибка?Сравни выражения для вычисления x1, x2, x3. Они должны быть однотипными, а у тебя выражение для x2 отличается от двух других. x2:=(b*b*+c*c-a*a)/(2*b*c); Красным выделен лишний знак умножения. Так, как у тебя было записано, выражение в скобках эквивалентно (b*b*c*c-a*a), а не (b*b+c*c-a*a), как следовало написать (и было написано в других случаях). Кстати, вопрос на засыпку , почему эквивалентно. Сразу подсказка: посмотри описание операции "унарный плюс". Я уже когда-то писал: компьютер никаких ошибок программирования не прощает, наоборот, работает по принципу "не было гвоздя - подкова пропала, подкова пропала - лошадь захромала, лошадь захромала - командир убит, конница разбита, армия бежит..." (из старого английского стишка). что должна прога выводить, если подкоренное выражение меньше нуля?Ну, хорошая прога в таком случае должна вывести нечто вроде "Извините, ошибка программиста. Пожалуйста, сообщите, при каких входных данных произошла эта ошибка. Это поможет нам улучшить программу. Спасибо!". На самом деле это та самая захромавшая лошадь из-за лишнего знака умножения. Подкоренное выражение на этом этапе выполнения программы не может быть отрицательным. Оно будет таким только для несуществующих треугольников, а эта возможность на данном этапе выполнения программы уже отсечена. А вопрос об углах и площадях несуществующих треугольников хотя и интересен с математической точки зрения (и его разбор дал бы способ построить программу экономнее: может ли существовать треугольник с заданными сторонами, можно было узнать без всяких сравнений сторон, просто по ходу вычисления площади), но не будем уходить далеко от тех баранов, какие у нас есть. Изменено 4 октября, 2006 пользователем Тролль Ссылка на комментарий Поделиться на другие сайты Поделиться
Бумер Опубликовано 5 октября, 2006 Автор Жалоба Поделиться Опубликовано 5 октября, 2006 Спасибо, сегодня попробую. Может быть защищу вторую лабу и тогда серьезно займусь третьей. Ссылка на комментарий Поделиться на другие сайты Поделиться
Бумер Опубликовано 7 октября, 2006 Автор Жалоба Поделиться Опубликовано 7 октября, 2006 Защитил вторую лабу, можете поздравить! Третью решил полностью пределатЬ, т.к. в ней много глюков и не учтено ОДЗ, которое от нас очень сильно требуют. вот код program lab_3;vara,b,c,a1,b1,c1,x1,x2,x3,s,min_ug, min_ug_grad,p: real;beginwrite ('wwedite a,b,c');readln (a,b,c);if ((a+b)>c) and ((a+c)>b) and ((b+c)>a) then beginwriteln ('Eti chisla mogut bit storonami treugolnika!');x1:=(a*a+b*b-c*c)/(2*a*b);c1:=(Pi/2)-arctan(x1/(sqrt(1-(x1*x1))));x2:=(b*b*+c*c-a*a)/(2*b*c);a1:=(Pi/2)-arctan(x2/(sqrt(1-(x2*x2))));x3:=(a*a+c*c-b*b)/(2*a*c);b1:=(Pi/2)-arctan(x3/(sqrt(1-(x3*x3)))); if a1<b1 then min_ug:=a1 else min_ug:=b1; if min_ug>c1 then min_ug:=c1;min_ug_grad:=(180/Pi)*min_ug;writeln ('Minimalnii ugol w treugolnike rawen ',min_ug:3:2,' radian ili ',min_ug_grad:3:2,' gradusow');p:=(a+b+c)/2;s:=sqrt(p*(p-a)*(p-b)*(p-c));writeln ('ploschad S=',s:3:2);readln; end else beginwriteln ('Eti chisla ne mogut bit storonami treugolnika');readln; endend. Прошу посмотреть эту прогу на налчие багов и проверить, соответствет ли она прикрепленному ниже алгоритму и если нет то что лучше подправить алгоритм или прогу и как?. Ссылка на комментарий Поделиться на другие сайты Поделиться
Тролль Опубликовано 7 октября, 2006 Жалоба Поделиться Опубликовано 7 октября, 2006 (изменено) Бумер: а) убери лишний знак умножения! Сколько об этом пишу, специально красным цветом его выделял, а воз и ныне там! б) ОДЗ у тебя проверяется сравнением сторон. Проверку, что введенные длины сторон положительны, легко добавить к сравнению сторон. Хотя, возможно, это и излишне, хуже от этого не будет. Тогда вместо if ((a+b)>c) and ((a+c)>b) and ((b+c)>a) пишем if (a+b>c) and (a+c>b) and (b+c>a) and (a>0) and (b>0) and (c>0) А проверять иксы, как это у тебя нарисовано на блок-схеме, ни к чему. Если треугольник существует, а это у тебя проверяется вначале, они всегда будут меньше 1. Поскольку уже установлено, что треугольник существует, у него обязаны иметься три угла, это незачем проверять отдельно. Изменено 7 октября, 2006 пользователем Тролль Ссылка на комментарий Поделиться на другие сайты Поделиться
Бумер Опубликовано 8 октября, 2006 Автор Жалоба Поделиться Опубликовано 8 октября, 2006 А код-то соответствует алгоритму? ЗЫ: лишний знак умнож. убрал! А лишнюю проверку ОДЗ от нас требуют! Ссылка на комментарий Поделиться на другие сайты Поделиться
Бумер Опубликовано 8 октября, 2006 Автор Жалоба Поделиться Опубликовано 8 октября, 2006 Вот последний, отлаженный вариант с моей точки зрения: program lab_3;vara,b,c,p,s,x1,x2,x3,min_ug,min_ug_grad,a1,b1,c1,max,max_grad: real;beginwriteln ('wwedite a='); readln(a);writeln ('wwedite b='); readln(b);writeln ('wwedite c='); readln ©;if (a+b>c) and (a+c>b) and (b+c>a) thenbegin if (a>0) and (b>0) and (c>0) then begin x1:=(b*b+c*c-a*a)/(2*b*c); x2:=(a*a+c*c-b*b)/(2*a*c); x3:=(a*a+b*b-c*c)/(2*a*b); if (x1<1) and (x2<1) and (x3<1) thenbegin a1:=Pi/2-arctan(x1/(sqrt(1-x1*x1))); b1:=Pi/2-arctan(x2/(sqrt(1-x2*x2))); c1:=Pi/2-arctan(x3/(sqrt(1-x3*x3))); min_ug:=a1; if min_ug>b1 then min_ug:=b1; if min_ug>c1 then min_ug:=c1; max:=a1; if max<b1 then max:=b1; if max<c1 then max:=c1; max_grad:=(180/Pi)*max; p:=(a+b+c)/2; s:=sqrt(p*(p-a)*(p-b)*(p-c)); min_ug_grad:=(180/Pi)*min_ug; if max_grad<90 thenbegin writeln('Ploshad S=',s:10:2); writeln ('Minimalnii ugol v treugolnike min_ug=',min_ug:10:2,'radian'); writeln( ' Ili', min_ug_grad:10:2,'gradusow'); endelse writeln ('treugolnik ne ostrougolnii');end end else writeln ('naruscheno ODZ');endelse writeln ('Eti chisla ne mogut bit storonami treugolnika');readln;end. Алгоритм тот же. ТАк соответствует ли этот код нарисованному алгоритму? Ссылка на комментарий Поделиться на другие сайты Поделиться
Тролль Опубликовано 8 октября, 2006 Жалоба Поделиться Опубликовано 8 октября, 2006 Соответствует. Ссылка на комментарий Поделиться на другие сайты Поделиться
Рекомендуемые сообщения
Для публикации сообщений создайте учётную запись или авторизуйтесь
Вы должны быть пользователем, чтобы оставить комментарий
Создать учетную запись
Зарегистрируйте новую учётную запись в нашем сообществе. Это очень просто!
Регистрация нового пользователяВойти
Уже есть аккаунт? Войти в систему.
Войти