Методы решения С1
Задача, 05 Мая 2010, автор: пользователь скрыл имя
Краткое описание
решения задач
Ответы на задачи С1:
Программа работает неправильно, если a и b не равны нулю и имеют разные знаки: в этом случае уравнение не имеет решений (поскольку модуль – неотрицательная величина), а программа выдаст два решения. Хотя в задании сказано «Приведите пример таких чисел a, b, x,…», значение x ни на что не влияет (см. далее), в ответе можно указать любое число x. Например,
Лишняя часть программы – ввод x, поскольку это не исходные данные, а результат. Поэтому вместо оператора
readln(a,b,x);
правильнее написать
readln(a,b);
Возможная доработка программы – добавить еще один условный оператор, обрабатывающий неучтенный случай (a и b не равны нулю и имеют разные знаки), при котором нет решений:
var a,b,x: 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, которое больше нуля, когда два значения имеют одинаковые знаки, и меньше нуля – когда разные
Содержимое работы - 1 файл
answC1.doc
— 330.00 Кб (Скачать файл)Ответы на задачи С1:
- Программа работает
неправильно, если a и b не равны нулю и имеют разные
знаки: в этом случае уравнение
не имеет решений
(поскольку модуль – неотрицательная
величина), а программа выдаст два решения.
Хотя в задании сказано «Приведите
пример таких чисел a, b, x,…», значение x
ни на что не влияет (см. далее), в ответе
можно указать любое число x. Например,
Лишняя часть программы – ввод x, поскольку это не исходные данные, а результат. Поэтому вместо оператора
readln(a,b,x);
правильнее написать
readln(a,b);
Возможная доработка программы – добавить еще один условный оператор, обрабатывающий неучтенный случай (a и b не равны нулю и имеют разные знаки), при котором нет решений:
var a,b,x: 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, которое больше нуля, когда два значения имеют одинаковые знаки, и меньше нуля – когда разные
- Программа работает
неправильно, если a и b равны нулю: в этом случае
решением уравнения
является любое
число x, а программа выдаст только
решение
. Хотя в задании
сказано «Приведите
пример таких чисел a, b, x,…», значение x
ни на что не влияет (см. далее), в ответе
можно указать любое число x. Например,
Лишняя часть программы – ввод x, поскольку это не исходные данные, а результат. Поэтому вместо оператора
readln(a,b,x);
правильнее написать
readln(a,b);
Возможная доработка программы – добавить еще один условный оператор, обрабатывающий неучтенный случай (a и b равны нулю), при котором решением является любое число:
var a,b,x: 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 ('точка не лежит внутри области');
- В этой программе
внешне все выглядит правильно, поэтому
весьма вероятно, что сделана «ловушка»
на какой-то особый (вырожденный) случай.
При решении квадратного
уравнения «особый случай» – это D > 0 не срабатывает и программа выдает сообщение «действительных корней нет». Поэтому, например, для программа работает неверно. При этом можно вводить любые x1 и x2 , поскольку в эти переменные записываются результаты вычислений (корни уравнения) анне исходные данные. Это ответ на второй вопрос: вместо оператораравенство дискриминанта нулю (два одинаковых корня). Проверяя его, сразу обнаруживаем, что при этом условие
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.
- Программа очень
плохо написана, мысль автора слабо прослеживается,
поэтому сложно разбираться в коде. Для
проверки четности числа используется
операция mod –остаток от деления целых
чисел. Очевидно, что если остаток от деления
a на 2 (записывается a mod 2) – нуль, то число a
делится на 2 без остатка, то есть – четное.
Для того, чтобы выяснить, когда программа будет работать неверно, можно использовать ручную прокрутку для четырех возможных вариантов: - оба числа четных
- a – четное, b – нечетное
- a – нечетное, b – четное
- оба числа нечетных
При этом обнаруживаем, что программа неверно работает во втором случае, например, для . Простейшая (?) доработка программы с сохранением замысла (?) автора может быть такая (расширено действие условного оператора и добавлен 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