Ответы на задачи 24 (С1)
Скачать 1.99 Mb.
|
© К. Поляков, 2009-2017 Ответы на задачи 24 (С1):
readln(a,b,x); правильнее написать readln(a,b); Переменная x далее не используется, поэтому ее не нужно объявлять: var a,b: real; Возможная доработка программы – добавить еще один условный оператор, обрабатывающий неучтенный случай (a и b не равны нулю и имеют разные знаки), при котором нет решений: var a,b: real; begin readln(a,b); if a = 0 then if b = 0 then write ('любое число') else write ('нет решений') else if b = 0 then write('x = 0') else if a*b < 0 then write('нет решений') else write('x =',b/a,' или x =',-b/a); end. обратите внимание, что для проверки условия «a и b имеют разные знаки» использовано произведение a*b, которое больше нуля, когда два значения имеют одинаковые знаки, и меньше нуля – когда разные
readln(a,b,x); правильнее написать readln(a,b); Переменная x далее не используется, поэтому ее не нужно объявлять: var a,b: real; Возможная доработка программы – добавить еще один условный оператор, обрабатывающий неучтенный случай (a и b равны нулю), при котором решением является любое число: var a,b: real; begin readln(a,b); if b = 0 then if a = 0 then write('любое число') else write('x = 0') else if a = 0 then write('нет решений') else write('x =',-b/a); end. можно еще немного оптимизировать программу: заметим, что в обеих частях первого условного оператора встречается оператор if a = 0 then; его можно «вынести» наверх, сделать внешним, а не вложенным: if a = 0 then if b = 0 then write('любое число') else write('нет решений') else write('x=',-b/a); если вы боитесь запутаться во вложенных условных операторах, можно использовать сложные условия и рассмотреть три возможных варианта (важно не забыть ни один!): if (a=0) and (b=0)then write('любое число'); if (a=0) and (b<>0)then write('нет решений'); if a <> 0 then write('x=',-b/a); здесь нужно убедиться, что для каждого варианта входных данных сработает один и только один условный оператор
по оси X: по оси Y: В программе не учитывается условие , причем оно не перекрывается другими условиями. Поэтому программа работает неправильно в том случае, когда и (область красного цвета на рисунке). Одна из таких точек: Для доработки программы нужно добавить еще один условный оператор с недостающим условием и соответствующий ему else-блок, выдающий сообщение в случае невыполнения этого условия: var x0, у0, у: real; begin readln (x0, y0); if (x0 < 2)then begin if (x0 > 0)then begin if (y0 > 0)then begin у := 2 – х0; if (y0 < у) then writeln ('точка лежит внутри области') else writein ('точка не лежит внутри области'); end else writeln ('точка не лежит внутри области'); end else writeln ('точка не лежит внутри области'); end else writeln ('точка не лежит внутри области'); end. Это решение работает, но громоздко и некрасиво. Заметим, что два условия и автоматически обеспечивают выполнение условия , которое становится лишним: if (x0 > 0)then begin if (y0 > 0)then begin у := 2 – х0; if (y0 < у) then writeln ('точка лежит внутри области') else writein ('точка не лежит внутри области'); end else writeln ('точка не лежит внутри области'); end else writeln ('точка не лежит внутри области'); Сделаем еще один шаг: попадание точки в заданную область равносильно одновременному выполнению (операция «И») трех условий: , и , поэтому получаем такой вариант с использованием сложного условия: if (x0 > 0) and (y0 > 0) and (y0 < 2 - x0) then begin writeln ('точка лежит внутри области') else writein ('точка не лежит внутри области');
readln(a,b,c,x1,x2); правильнее написать readln(a,b,c); Чтобы исправить программу, достаточно вместо условия D > 0 написать D >= 0: var a, b, с, D, xl, x2: real; begin readln(a, b, с); D := b*b - 4*a*c; if D >= 0 then begin xl := (-b + sqrt(D))/(2*a); x2 := (-b - sqrt(D))/(2*a); write('xl =', xl); write('x2 =', x2); end else writeln ('действительных корней нет'); end.
При этом обнаруживаем, что программа неверно работает во втором случае, например, для . Простейшая (?) доработка программы с сохранением замысла (?) автора может быть такая (расширено действие условного оператора и добавлен else-блок) var a, b: integer; begin readln(a, b); a := a mod 2; if a > 0 then begin b := b mod 2; if b > 0 then writeln ('четных чисел нет') else writeln ('четное число есть'); end else writeln ('четное число есть'); end. Чтобы сделать программу красивой и понятной, запишем на Паскале вполне ясное условие: «если a – четное или b – четное, то четное число есть, иначе – нет»: var a, b: integer; begin readln(a, b); if (a mod 2 = 0) or (b mod 2 = 0) then writeln ('четное число есть') else writeln ('четных чисел нет') end.
var х, у, z: real; begin readln (x, у, z); if (x + y > z) then begin if (x + z > y) then if (y + z > x) then writeln('треугольник построить можно') else writeln('треугольник построить нельзя') else writeln('треугольник построить нельзя'); end else writeln('треугольник построить нельзя'); end. Чтобы сделать программу красивой и понятной, нужно понять, что треугольник можно построить только в случае одновременного выполнения всех трех условий; в программе их нужно связать операцией and («И»): var х, у, z: real; begin readln (x, у, z); if (x + y > z) and (x + z > y) and (y + z > x) then writeln('треугольник построить можно') else writeln('треугольник построить нельзя'); end.
var x, у, rl,r2:real; h: real; begin readln (x, у, rl, r2); h:= sqrt (x*x + y*y); if (h < rl) AND (h > r2) then writeln ('точка А лежит внутри кольца'); if (h < r2) AND (h > r1) then writeln ('точка А лежит внутри кольца'); end. Более красивый способ – объединить два сложных условия в одно с помощью операции or («ИЛИ»), поскольку и в том, и в другом случае выдается одинаковое сообщение: var x, у, rl,r2:real; h: real; begin readln (x, у, rl, r2); h := sqrt(x*x + y*y); if (h < rl) AND (h > r2) OR (h < r2) AND (h > r1) then writeln('точка А лежит внутри кольца'); end. Обратите внимание на то, что операция OR имеет более низкий приоритет, чем AND, поэтому в этом сложном условии она будет выполняться последней, как и требуется. Остается ответить на третий вопрос: как можно обойтись без операций AND или OR. Конечно, возможен «лобовой» вариант, использующий вложенные условные операторы: if h < rl then if h > r2 then writeln('точка А лежит внутри кольца'); if h > rl then if h < r2 then writeln('точка А лежит внутри кольца'); Обратите внимание, что нам понадобилось отдельно «обойти» случай h = r1, потому что по условию понятие «внутри кольца» рассматривается в строгом смысле и при h = r1 считается, что точка не попадает в кольцо. Для более грамотного решения задачи нужно попробовать использовать арифметические операции, так чтобы результат вычисления некоторого выражения прямо отвечал на нужный вопрос. Поскольку числа могут быть самые разные, лучше «играть» не на конкретных значениях, а на знаке, то есть, если точка находится внутри кольца, выражение должно быть, скажем, отрицательным, а если нет – то положительным. Или наоборот. Если точка находится внутри кольца, то находится h между r1 и r2. Это значит, что разности h-r1 и h-r2 имеют разный знак, следовательно, их произведение отрицательно1. Таким образом, красиво написанная программа может иметь, например, такой вид: var x, у, rl,r2:real; h: real; begin readln (x, у, rl, r2); h := sqrt(x*x + y*y); if (h - rl)*(h - r2) < 0 then writeln('точка А лежит внутри кольца'); end.
Кроме того, если условие в первом условном операторе истинно, а одно из последующих – ложно, программа вообще не выдает сообщения на экран, это неверно. Таким образом, для входных данных или программа также работает неверно. Чтобы исправить эти ошибки «в лоб», можно добавить еще один условный оператор, проверяющий недостающее условие y0 > -2, и добавить else-блоки, чтобы выводить сообщение «не лежит внутри области» при нарушении любого из условий: var x0, y0: real; begin readln (x0, y0); if(x0 < 2)then begin if(x0 > -2)then if (y0 < 2) then if (y0 > -2) then writeln('точка лежит внутри области') else writeln('точка не лежит внутри области') else writeln('точка не лежит внутри области') else writeln('точка не лежит внутри области'); end else writeln('точка не лежит внутри области'); end. чтобы сделать красивую программу, нужно перевести на Паскаль сложное условие «точка лежит внутри области, если одновременно выполняются четыре условия…»; слова «одновременно выполняются» говорят о том, что нужно использовать логическую операцию and («И»): |