Методы решения С1

Автор работы: Пользователь скрыл имя, 05 Мая 2010 в 20:46, задача

Краткое описание

решения задач
Ответы на задачи С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:

  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. Программа работает неправильно, если 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);

    здесь нужно убедиться, что для каждого варианта входных  данных сработает один и только один условный оператор

 
  1. Согласно условию, нас интересует область, закрашенная  на рисунке серым цветом. Если рассмотреть  границы области по осям координат, получим четыре условия:

      по оси 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 ('точка не лежит внутри области');

 
  1. В этой программе  внешне все выглядит правильно, поэтому  весьма вероятно, что сделана «ловушка»  на какой-то особый (вырожденный) случай. При решении квадратного уравнения  «особый случай» – это равенство  дискриминанта нулю (два одинаковых корня). Проверяя его, сразу обнаруживаем, что при этом условие 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.

  1. Программа очень плохо написана, мысль автора слабо прослеживается, поэтому сложно разбираться в коде. Для проверки четности числа используется операция mod –остаток от деления целых чисел. Очевидно, что если остаток от деления a на 2 (записывается a mod 2) – нуль, то число a делится на 2 без остатка, то есть – четное.  
    Для того, чтобы выяснить, когда программа будет работать неверно, можно использовать ручную прокрутку для четырех возможных вариантов:
    1. оба числа четных
    2. a – четное, b – нечетное
    3. a – нечетное, b – четное
    4. оба числа нечетных

    При этом обнаруживаем, что программа неверно работает во втором случае, например, для  . Простейшая (?) доработка программы с сохранением замысла (?) автора может быть такая (расширено действие условного оператора  и добавлен 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

Информация о работе Методы решения С1