Writeln('точка лежит внутри области')



Else writeln('точка не лежит внутри области')

Else writeln('точка не лежит внутри области')

else writeln('точка не лежит внутри области');

End

else writeln('точка не лежит внутри области');

End.

чтобы сделать красивую программу, нужно перевести на Паскаль сложное условие «точка лежит внутри области, если одновременно выполняются четыре условия…»; слова «одновременно выполняются» говорят о том, что нужно использовать логическую операцию and («И»):

var x0, y0: real;

Begin

Readln (x0, y0)

if (x0 < 2) and (x0 > -2) and

(y0 < 2) and (y0 > -2) then

Writeln('точка лежит внутри области')

else writeln('точка не лежит внутри области');

End.

 

                8
                7
                6
                5
                4
                3
                2
            1
1 2 3 4 5 6 7 8  

9) Легко проверить, что клетка (i=5,j=4) удовлетворяет условию i=9-j, и, следовательно,  сложному условию (i=9-j) OR (i=j) (OR означает логическую операцию «ИЛИ» - выполнение хотя бы одного из двух условий)

Для ответа на остальные вопросы нарисуем поле и расставим королей (в самом деле в этой задаче все равно, какого цвета поля, поэтому мы их не раскрашивали).

Короли могут ходить по диагонали, поэтому чтобы дойти до поля (i,j), королю лучше

сначала идти по диагонали, чтобы быстрее выйти на нужную горизонталь или вертикаль, а затем двигаться по этой горизонтали (или вертикали) к заданной клетке.

· черный король [его координаты (1,1)] идет по диагонали k-1 шагов, где k=min(i,j) до клетки с координатами (i,i) (если i<=j) или до клетки (j,j) (если i>=j); затем он делает оставшееся количество шагов,  max(i,j)-k, по горизонтали или вертикали, так что его общее число шагов равно

Max(i,j)-1

· аналогично белый король [его координаты (8,1)] идет по диагонали q-1 шагов, где q=min(9-i,j) до клетки с координатами (9-i,9-i) (если 9-i<=j) или до клетки (j,j)(если 9-i>=j); затем он делает оставшееся количество шагов, max(9-i,j)-q, по горизонтали или вертикали, так что его общее число шагов равно

Max(9-i,j)-1

· таким образом, нас интересуют клетки (i,j), для которых

max(i,j)-1= max(9-i,j)-1 или  max(i,j)= max(9-i,j)   (*)

(1,8) (2,8)             8
(1,7)               7
              (8,6) 6
        (5,5)       5
                4
                3
                2
            1
1 2 3 4 5 6 7 8  

Чтобы найти все пары (i,j), для которых верно полученное равенство, рассмотрим сначала левую половину доски (i<=4):

· если i<=4, то 9-i>=5>i, поэтому равенство (*) справедливо только при j>=9-i; это область выше главной диагонали и на ней;

· в силу симметрии сразу можно построить соответствующую область и в правой части доски (см. рисунок справа):

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

(i=1, j=8), (i=2, j=8), (i=1, j=7),
(i=5, j=5), (i=8, j=6)

Правильное условие, определяющее нужную область, выглядит так: «клетка выше главной диагонали (или на ней) и одновременно выше второй диагонали (или на ней)». Остается записать его на Паскале:

 (j>=i) and (j>=9-i)

Доработка программы сводится просто к замене условия, все остальное правильно.

10) Попробуем прежде всего найти математическое решение неравенства . Оно истинно, если числитель и знаменатель дроби имеют один знак, или оба положительные, или оба отрицательные. При  получаем:

(  и ) или (  и )

В краткой форме:  или . В зависимости от значения  получаем

Случай 1. При  и :  или

Случай 2. При  и :  или

Теперь рассмотрим случай . Снова получаем два варианта:

(  и ) или (  и )

При  всегда ложно выражение в первых скобках, а при  – выражение во вторых скобках. Поэтому можно записать еще два случая через двойные неравенства:

Случай 3. При  и :

Случай 4. При  и :

Запишем основную часть программы, определив принадлежность каждого else-блока и используя запись «лесенкой»:

if b > 0 then

write('x > ', a, ' или x < 0')

Else

if a > 0 then

write('0 < x < ', a)

Else

write(a, ' < x < 0');

Анализ условных операторов показывает, что неправильно обрабатывается Случай 2 (  и ), то есть, в качестве примера можно привести пару  при любом  (которое вообще не влияет на результат).

В программе вводится переменная , которая нигде не используется. Поэтому это – лишняя часть программы, можно убрать  из списка объявляемых переменных и списка ввода в операторе readln.

Простейший и (в данной задаче) наиболее логичный вариант доработки программы – добавить еще один условный оператор для правильного разделения Случая 1 и Случая 2:

var a, b: real;

Begin

readln(a, b);

if b > 0 then

if a > 0 then

write('x > ', a, ' или x < 0')

Else

write('x < ', a, ' или x > 0')

Else

if a > 0 then

write('0 < x < ', a)

Else

write(a, ' < x < 0');

End.

11) Первое условие в программе, x*x+y*y >= 4, означает «вне круга». Если выполняются одновременно второе и третье условия, x <= 2и y <= x, точка находится в секторе между прямыми  и , в который входит заштрихованная область. Таким образом, выполнение всех трех условия означает «вне круга и в секторе». Однако, этому условию удовлетворяет не только заштрихованная  область, но еще и вся бесконечная область, выделенная на рисунке красным цветом. Поэтому для любой точки в «красной зоне», например, для точки (1;­ –2), программа выдаст неправильный ответ «принадлежит».

Если записать программу «лесенкой», становится видна еще одна ошибка.

if x*x+y*y >= 4 then

if x <= 2 then

if y <= x then

Write('принадлежит')

Else

Write('не принадлежит')

Дело в том, что любой else относится к ближайшему if, поэтому сообщение «не принадлежит» выводится только тогда, когда первые два условия выполняются, а третье – нет. Следовательно, для точки (0;0), например,  программа вообще не выдаст никакого сообщения (первое условие ложно).

Чтобы исправить программу, можно добавить еще одно условие y >= 0 (это отсекает «красную зону») и объединить все четыре условия в одно сложное условие:

var x,y: real;

Begin

readln(x,y);

if (x*x+y*y >= 4) and (x <= 2) and

(y <= x) and (y >= 0) then

Write('принадлежит')

Else

Write('не принадлежит')

End.

 

12) Записанные в программе условия означают «ниже синусоиды» и в секторе между прямыми  и , в который входит заштрихованная область. Однако, этому условию удовлетворяет не только заштрихованная область, но еще и вся бесконечная область, выделенная на рисунке красным цветом. Первое пересечение синусоиды с осью абсцисс происходит при , поэтому программа выдает неверный ответ «принадлежит», например, для точки (-4;0), которая в самом деле не принадлежит заштрихованной области.

Если записать программу «лесенкой», становится видна еще одна ошибка.

if y >= -1 then

if y <= sin(x) then

if y >= x-1 then

Write('принадлежит')

Else

Write('не принадлежит')

Дело в том, что любой else относится к ближайшему if, поэтому сообщение «не принадлежит» выводится только тогда, когда первые два условия выполняются, а третье – нет. Следовательно, для точки (0;-2), например, программа вообще не выдаст никакого сообщения (первое условие ложно).

Чтобы исправить программу, можно добавить еще одно условие x >= -pi/2 (это отсекает «красную зону») и объединить все четыре условия в одно сложное условие:

var x,y: real;

Begin

readln(x,y);

if (y >= -1) and (y <= sin(x)) and

(y >= x-1) and (x >= -pi/2) then

Write('принадлежит')

Else

Write('не принадлежит')

End.

13) Эта задача полностью аналогична задаче 11 (рисунки симметричны). Вот основная часть программы с выделенной структурой:

if x*x+y*y >= 4 then

if x >= -2 then

if y <= -x then

Write('принадлежит')

Else

Write('не принадлежит')

Для точек в «красной зоне» (см. рисунок) программа ошибочно выдает ответ «принадлежит», а для точек, в которых не выполняется первое или второе условие (внутри круга или слева от прямой ) вообще не выдается никакого сообщения.

Чтобы исправить программу, можно добавить еще одно условие y >= 0 (это отсекает «красную зону») и объединить все четыре условия в одно сложное условие:

 

var x,y: real;

Begin

readln(x,y);

if (x*x+y*y >= 4) and (x >= -2) and

(y <= -x) and (y >= 0) then

Write('принадлежит')

Else

Write('не принадлежит')

End.

14) Условный оператор

if a > b then begin x:=a; a:=b; b:=x; end;

упорядочивает переменные a и b с помощью вспомогательной переменной x, записывая в переменную a минимальное из двух значений а в переменную b – максимальное. Аналогично оператор

if b > c then begin x:=b; b:=c; c:=x; end;

упорядочивает значения b и с.

Очевидно, что x используется только как вспомогательная переменная, поэтому вводить ее с клавиатуры не нужно, оператор ввода должен выглядеть так:

read(a, b, c);

Программа работает неправильно, если минимальное число вводится последним и попадает в переменную c. Действительно, выполняя программу для a=3, b=2 и c=1 получаем

a b c
readln(a, b, c, x); 3 2 1
if a > b then begin x:=a; a:=b; b:=x; end; 2 3 1
if b > c then begin x:=b; b:=c; c:=x; end; 2 1 3

Чтобы исправить ошибку, в конец программы нужно добавить строчку, упорядочивающую a и b (точную копию первого условного оператора). Вот исправленная программа

var a, b, c, x: integer;

Begin

read(a, b, c);

if a > b then begin x:=a; a:=b; b:=x; end;

if b > c then begin x:=b; b:=c; c:=x; end;

if a > b then begin x:=a; a:=b; b:=x; end;

write(a,b,c);

End.

15) В приведенной программе две ошибки. Во-первых, условия

y <= sin(x)

y <= 0.5

y >= 0

выделяют не только заштрихованную область, но и аналогичные области в каждой полуволне (на рисунке они обозанчены красным цветом).

Например, для точки  программа ошибочно выдаст ответ «принадлежит». Поэтому нужны два дополнительных ограничения по координате x (для заданной области – ):

x <= pi (или, например, x <= 4)

x >= 0

Во-вторых, записав программу «лесенкой» с выделением структуры

if y <= sin(x) then

if y <= 0.5 then

if y >= 0 then

Write('принадлежит')

Else

   write('не принадлежит');

мы видим, что else-блок относится только к последнему условному оператору, поэтому сообщение «не принадлежит» не будет выведено, если одно из первых двух условий ложно. Поэтому, например, для точки  программа не выдаст вообще никакого ответа, то есть, сработает неверно.

Самый простой способ доработки программы – использовать одно сложное условие, определяющее именно заштрихованную область (с ограничением по оси x)

var x, y: real;

Begin

readln(x, y);

if (y <= sin(x)) and (y <= 0.5) and (y >= 0) and

(x >= 0) and (x <= pi) then

Write('принадлежит')

Else

write('не принадлежит');

End.

16) В приведенной программе две ошибки. Во-первых, условия

y <= x

y <= -x

y >= x*x-2

выполненные одновременно, выделяют только область, обозначенную на рисунке синим цветом, а не всю заштрихованную область (серую). То есть для точек, попавших в серую область, но не попавших в синюю (например, для точки ), ответ будет неверный.

Во-вторых, записав программу «лесенкой» с выделением структуры

if y <= x then

if y <= -x then

if y >= x*x-2 then

Write('принадлежит')

Else

   write('не принадлежит');

мы видим, что else-блок относится только к последнему условному оператору, поэтому сообщение «не принадлежит» не будет выведено, если одно из первых двух условий ложно. Поэтому, например, для точки  программа не выдаст вообще никакого ответа, то есть, сработает неверно.

Самый простой вариант добаботки – построить одно сложное условие, причем для того, чтобы охватить всю серую область, условия y < x и y < -x должны быть связаны с помощью логической операции «ИЛИ» (в Паскале – or):

if ((y <= x) or (y <= -x)) and (y >= x*x-2) then

Write('принадлежит')

Else

write('не принадлежит');

Обратите внимание, что два первых условия, связанные с помощью or, взяты в скобки, потому что иначе операция and выполнится раньше, чем or, и результат будет неверный.

Вот полная программа:

var x, y: real;

Begin

readln(x, y);

if ((y <= x) or (y <= -x)) and (y >= x*x-2) then

Write('принадлежит')

Else

write('не принадлежит');

End.

17) В приведенной программе две ошибки. Во-первых, условия

y >= x

y >= 0

y <= 2-x*x

выполненные одновременно, выделяют только область, обозначенную на рисунке синим цветом, а не всю заштрихованную область (серую). То есть для точек, попавших в серую область, но не попавших в синюю (например, для точки ), ответ будет неверный.

Во-вторых, записав программу «лесенкой» с выделением структуры

if y >= x then

if y >= 0 then

if y <= 2-x*x then

Write('принадлежит')

Else

   write('не принадлежит');

мы видим, что else-блок относится только к последнему условному оператору, поэтому сообщение «не принадлежит» не будет выведено, если одно из первых двух условий ложно. Поэтому, например, для точки  программа не выдаст вообще никакого ответа, то есть, сработает неверно.

Самый простой вариант добаботки – построить одно сложное условие, причем для того, чтобы охватить всю серую область, условия y < x и y < -x должны быть связаны с помощью логической операции «ИЛИ» (в Паскале – or):

if ((y >= x) or (y >= 0)) and (y <= 2-x*x) then

Write('принадлежит')

Else

write('не принадлежит');

Обратите внимание, что два первых условия, связанные с помощью or, взяты в скобки, потому что иначе операция and выполнится раньше, чем or, и результат будет неверный.

Вот полная программа:

var x, y: real;

Begin

readln(x, y);

if ((y >= x) or (y >= 0)) and (y <= 2-x*x) then

Write('принадлежит')

Else

write('не принадлежит');

End.

 

18) В приведенной программе две ошибки. Во-первых, условия

y >= x

x <= 0

x*x+y*y <= 1

выполненные одновременно, выделяют только область, обозначенную на рисунке синим цветом, а не всю заштрихованную область (серую). То есть для точек, попавших в серую область, но не попавших в синюю (например, для точки ), ответ будет неверный.

Во-вторых, записав программу «лесенкой» с выделением структуры

if y >= x then

if x <= 0 then

if x*x+y*y <= 1 then

Write('принадлежит')

Else

   write('не принадлежит');

мы видим, что else-блок относится только к последнему условному оператору, поэтому сообщение «не принадлежит» не будет выведено, если одно из первых двух условий ложно. Поэтому, например, для точки  программа не выдаст вообще никакого ответа, то есть, сработает неверно.

Самый простой вариант добаботки – построить одно сложное условие, причем для того, чтобы охватить всю серую область, условия y < x и y < -x должны быть связаны с помощью логической операции «ИЛИ» (в Паскале – or):

if ((y >= x) or (x <= 0)) and (x*x+y*y <= 1) then

Write('принадлежит')

Else

write('не принадлежит');

Обратите внимание, что два первых условия, связанные с помощью or, взяты в скобки, потому что иначе операция and выполнится раньше, чем or, и результат будет неверный.

Вот полная программа:

var x, y: real;

Begin

readln(x, y);

if ((y >= x) or (x <= 0)) and (x*x+y*y <= 1) then

Write('принадлежит')

Else

write('не принадлежит');

End.

 

19) В приведенной программе две ошибки. Во-первых, условия

y <= x

y >= -x

x*x+y*y <= 1

выполненные одновременно, выделяют только область, обозначенную на рисунке синим цветом, а не всю заштрихованную область (серую). То есть для точек, попавших в серую область, но не попавших в синюю (например, для точки ), ответ будет неверный.

Во-вторых, записав программу «лесенкой» с выделением структуры

if y <= x then

if y >= -x then

if x*x+y*y <= 1 then

Write('принадлежит')

Else

   write('не принадлежит');

мы видим, что else-блок относится только к последнему условному оператору, поэтому сообщение «не принадлежит» не будет выведено, если одно из первых двух условий ложно. Поэтому, например, для точки  программа не выдаст вообще никакого ответа, то есть, сработает неверно.

Самый простой вариант добаботки – построить одно сложное условие, причем для того, чтобы охватить всю серую область, условия y < x и y < -x должны быть связаны с помощью логической операции «ИЛИ» (в Паскале – or):

if ((y <= x) or (y >= -x)) and (x*x+y*y <= 1) then

Write('принадлежит')

Else

write('не принадлежит');

Обратите внимание, что два первых условия, связанные с помощью or, взяты в скобки, потому что иначе операция and выполнится раньше, чем or, и результат будет неверный.

Вот полная программа:

var x, y: real;

Begin

readln(x, y);

if ((y <= x) or (y >= -x)) and (x*x+y*y <= 1) then

Write('принадлежит')

Else

write('не принадлежит');

End.

 

20) В приведенной программе несколько ошибок. Во-первых, заштрихованная область ограничена тремя прямыми: x=0, y=0 и y=x/2-1 и определяется условиями

x0 > 0

y0 < 0

y0 > x0/2-1

а в программе использована совершенно другая система условий. Во-вторых, в конце программы, независимо от выполнения условных операторов, всегда выводится сообщение «не принадлежит». Например, при вводе координат (1,–3) будет выведено сообщение «принадлежитне принадлежит», поэтому для этих данных она работает неверно.

Доработать программу очень просто – нужно составить сложное условие, объединив три правильных условия с помошью операции И (and):

var x0, y0: real;

Begin

readln(x0, y0);

if (x0 > 0) and (y0 < 0) and (y0 > x0/2-1) then

Write('принадлежит')

Else

write('не принадлежит');

End.


21) Прежде всего, перепишем условия в программе так, чтобы была видна их связь с уравнениями заданных прямых:

x-y >= -2 заменим на равносильное y <= x+2

x+y <= 2  заменим на равносильное y <= 2-x

Далее замечаем, что в программе else относится к последнему оператору if, то есть в самом деле структура кода такова:

if y <= x*x then

if y <= x+2 then

if y <= 2-x then

Write('принадлежит')

Else

   write('не принадлежит');

Это значит, что, например, при невыполнении первого условия (y <= x*x) (или при выполнении первого и невыполнении второго) вообще никакого сообщения не выводится, поскольку внутренний условный оператор, содержащий else-блок, не срабатывает. Таким образом, для точки (0,1), например, программа работает неправильно – не выводит никакого ответа.

Кроме того, системе из трех условий, которую использовал программист, удовлетворяют точки не только в «серой» области (которая нужна по условию задачи), но и в «красной» (см. рисунок). Поэтому, например, для точки (0,-1) будет ошибочно выдано соощение «принадлежит».

Для исправления этих ошибок нужно добавить условие y >= 0 и объединить все 4 условия с помощью операции И (в паскале – and) в одно сложное условие в одном условном операторе:

var x, y: real;

Begin

readln(x, y);

if (y <= x*x) and (y <= x+2) and (y <= 2-x) and (y >=0)
then

Write('принадлежит')

Else

write('не принадлежит');

End.

 

22) Особенность этой задачи в том, что одной из ограничительных линий используется гипербола, которая состоит из двух ветвей. Одна из этих ветвей на исходном рисунке не показана. Использованное в программе условие x*y >= 1 равносильно условию  для положительных  (это область выше показанной ветви гиперболы) и условию  для отрицательных  (это «красная» область ниже второй, не показанной ветви).

Далее замечаем, что в программе else относится к последнему оператору if, то есть в самом деле структура кода такова:

if x*y >= 1 then

if x <= 2 then

if y <= 2 then

Write('принадлежит')

Else

write('не принадлежит');

Это значит, что, например, при невыполнении первого условия (x*y >= 1) (или при выполнении первого и невыполнении второго) вообще никакого сообщения не выводится, поскольку внутренний условный оператор, содержащий else-блок, не срабатывает. Таким образом, для точки (0,0), например, программа работает неправильно – не выводит ответ вообще.

Кроме того, с учетом второй ветви гиперболы, системе из трех условий, которую использовал программист, удовлетворяют точки не только в «серой» области (которая нужна по условию задачи), но и в «красной» (см. рисунок). Поэтому, например, для точки (-2,-2) будет ошибочно выдано сообщение «принадлежит».

Для исправления этих ошибок нужно добавить условие x > 0 и объединить все 4 условия с помощью операции И (в паскале – and) в одно сложное условие в одном условном операторе:

var x, y: real;

Begin

readln(x, y);

if (x*y >= 1) and (x <= 2) and (y <= 2) and (x > 0) then

Write('принадлежит')

Else

write('не принадлежит');

End.

23) Сразу замечаем, что в программе else относится к последнему оператору if, то есть в самом деле структура кода такова:

if y >= 0 then

if y <= 1 then

if x >= 0 then

if x <= pi then

   if y <= sin(x) then

Write('принадлежит')

Else

      write('не принадлежит');

Это значит, что, например, при невыполнении первого, второго или третьего условий вообще никакого сообщения не выводится, поскольку внутренний условный оператор, содержащий else-блок, не срабатывает. Таким образом, для точки (-1,0), например, программа работает неправильно – не выводит ответ вообще.

Кроме того, в программе есть и другая ошибка. Легко видеть, что первые 4 условия определяют прямоугольник, в котором заключена нужная нам область – это правильно. В то же время пятое условие (y <= sin(x)) «отсекает» область, обозначенную желтым цветом, это неправильно. Таким образом, например, для точки (3;0,8), находящейся в «желтой» области, программы выдает неправильный ответ: «не принадлежит».

Поэтому нужно в пятом условии к области y <= sin(x) добавить еще область
x >= pi/2 (с учетом первых четырех условий, добавляется прямоугольник, показанный на рисунке красной рамкой). Объединение областей выполняется с помощью логической операции ИЛИ (в Паскале – or). Таким образом, вместо пятого условия нужно использовать сложное условие

( y <= sin(x)) or (x >= pi/2)

Кроме того, полученные 5 условий нужно объединить в одно сложное с помощью операции И (в Паскале – and):

var x, y: real;

Begin

readln(x, y);

if (y >= 0) and (y <= 1) and (x >= 0) and (x <= pi) and

((y <= sin(x)) or (x >= pi/2)) then

Write('принадлежит')

Else

write('не принадлежит');

End.

24) Сразу замечаем, что в программе else относится к последнему оператору if, то есть в самом деле структура кода такова:

if x <= 1 then

if y <= 1 then

if x*x + y*y <= 1 then

Write('принадлежит')

else write('не принадлежит');

Программа выводит сообщение «принадлежит» только тогда, когда выполняются все три условия, то есть, для всех точек внутри круга (синяя область), тогда как для «угла», который остался серым, будет выдано сообщение «не принадлежит» (поскольку первые два условия выполняются, а третье – нет). Таким образом, например, для точки (0,9;0,9) будет неверно выдано сообщение «не принадледжит». Итак на первый вопрос может быть такой:

Точка (0,9;0,9) находится в выделенной области. Для нее выполняются условия x<=1 и y<=1, но не выполняется условие x*x+y*y <=1. В этом случае приведенная программа выдает неверный ответ «не принадлежит».

Кроме того, для точек, для которых не выполняется любое из первых двух условий, вообще никакого сообщения не выдается. Поэтому в качестве примера неверной работы программы можно указать, например, точку (1,5;1,5). Тогда на первый вопрос можно ответить и так:

Для точки (1,5;1,5) не выполняется условие x<=1. В этом случае приведенная программа работает неправильно – не выдает вообще никакого ответа.

Для исправления программы лучше всего составить новое сложное условие. Выделенная область может быть получена как объединение двух областей: круга x*x + y*y <= 1 и квадрата с единичной стороной, левый нижний угол которого находится в начале координат:

if (x*x + y*y <= 1) { круг }

Or

((x >= 0) and (x <= 1) and { квадрат}

 (y >= 0) and (y <= 1))   

Then write('принадлежит')

else write('не принадлежит');

25) Сразу замечаем, что в программе else относится к последнему оператору if, то есть в самом деле структура кода такова:

if y >= 0 then

if x <= 1 then

if y >= x*x then

    write('принадлежит')

else write('не принадлежит');

Программа выводит сообщение «принадлежит» только тогда, когда выполняются все три условия, то есть, для всех точек внутри синей области, тогда как для «угла», который остался серым, будет выдано сообщение «не принадлежит» (поскольку первые два условия выполняются, а третье – нет). Таким образом, например, для точки (0,9;0,1) будет неверно выдано сообщение «не принадледжит». Итак на первый вопрос может быть такой:

Точка (0,9;0,1) находится в выделенной области. Для нее выполняются условия y>=0 и x<=1, но не выполняется условие y >= x*x. В этом случае приведенная программа выдает неверный ответ «не принадлежит».

Кроме того, для точек, для которых не выполняется любое из первых двух условий, вообще никакого сообщения не выдается. Поэтому в качестве примера неверной работы программы можно указать, например, точку (0;-1). Тогда на первый вопрос можно ответить и так:

Для точки (0;-1) не выполняется условие y>=0. В этом случае приведенная программа работает неправильно – не выдает вообще никакого ответа.

Для исправления программы лучше всего составить новое сложное условие. Выделенная область может быть получена как объединение двух областей: области выше параболы y >= x*xи квадрата с единичной стороной, левый нижний угол которого находится в начале координат:

if ((y >= x*x) and (x <= 1))  { над параболой }

Or

((x >= 0) and (x <= 1) and { квадрат}

(y >= 0) and (y <= 1))   

Then write('принадлежит')

else write('не принадлежит');

Для квадрата ограничение сверху по координате Y несущественно (вся область прямо над квадратом выделена), и можно заменить квадрат на верхнюю часть полосы, убрав последнее условие:

if ((y >= x*x) and (x <= 1)) { над параболой }

Or

((x >= 0) and (x <= 1) and (y >= 0))   

Then write('принадлежит')

else write('не принадлежит');

26) Сразу замечаем, что в программе else относится к последнему оператору if, то есть в самом деле структура кода такова:

if x <= 1 then

if y >= 1-x then

if y >= x*x then

Write('принадлежит')

else write('не принадлежит');

Программа выводит сообщение «принадлежит» только тогда, когда выполняются все три условия, то есть, для всех точек внутри синей области, тогда как для «угла», который остался серым, будет выдано сообщение «не принадлежит» (поскольку первые два условия выполняются, а третье – нет). Таким образом, например, для точки (0,9;0,5) будет неверно выдано сообщение «не принадледжит». Итак на первый вопрос может быть такой:

Точка (0,9;0,5) находится в выделенной области. Для нее выполняются условия x<=1 и y>=1-x, но не выполняется условие y >= x*x. В этом случае приведенная программа выдает неверный ответ «не принадлежит».

Кроме того, для точек, для которых не выполняется любое из первых двух условий, вообще никакого сообщения не выдается. Поэтому в качестве примера неверной работы программы можно указать, например, точку (2;0). Тогда на первый вопрос можно ответить и так:

Для точки (2;0) не выполняется условие x<=1. В этом случае приведенная программа работает неправильно – не выдает вообще никакого ответа.

Для исправления программы лучше всего составить новое сложное условие. Выделенная область может быть получена как объединение двух областей: синей области выше параболы y >= x*xи линии y = 1-x и (одновременно) слева от прямой x = 1, и верхней части полосы 0<=x<=1, которая снизу ограничена линией y = 1-x:

if ((y >= x*x) and (y >= 1-x) and (x <= 1)) 

{ синяя область над параболой и прямой }

Or

((x >= 0) and (x <= 1) and (y >= 1-x)) { полоса над прямой }

Then write('принадлежит')

else write('не принадлежит');

Это условие можно немного упростить, заметив, что условия y >= 1-x и x <= 1 встречаются в условиях для обеих областей:

 

if (y >= 1-x) and   { над прямой }

(x <= 1) and { слева от прямой x = 1} 

     ((y >= x*x) or { выше параболы }

      (x >= 0))     { справа от прямой x = 0 } 

Then write('принадлежит')

else write('не принадлежит');

27) Сразу замечаем, что в программе else относится к последнему оператору if, то есть в самом деле структура кода такова:

if x >= 0 then

if y <= 1 then

if (x*x + y*y <= 1) and (y >= x-1)

Then

Write('принадлежит')

else write('не принадлежит');

Программа выводит сообщение «принадлежит» только для всех точек внутри синей области, в которой одновременно выполняются все 4 условия. Для «угла» и части круга, которые показаны серым цветом, будет выдано сообщение «не принадлежит» (поскольку первые два условия выполняются, а третье – нет). Таким образом, например, для точки (1;0,75) будет неверно выдано сообщение «не принадледжит». Итак на первый вопрос может быть такой:

Точка (1;0,75) находится в выделенной области. Для нее выполняются условия x>=0 и y<=1, но не выполняется условие (x*x + y*y <= 1) and (y >= x-1).

В этом случае приведенная программа выдает неверный ответ «не принадлежит».

Кроме того, для точек, для которых не выполняется любое из первых двух условий, вообще никакого сообщения не выдается. Поэтому в качестве примера неверной работы программы можно указать, например, точку (-1;0). Тогда на первый вопрос можно ответить и так:

Для точки (-1;0) не выполняется условие x>=0. В этом случае приведенная программа работает неправильно – не выдает вообще никакого ответа.

Для исправления программы лучше всего составить новое сложное условие. Выделенная область может быть получена как объединение двух областей: полукруга

(x >= 0) and (x*x + y*y <= 1)

и треугольника

(x >= 0) and (y <= 1) and (y >= x-1)

Получаем:

if ((x >= 0) and (x*x + y*y <= 1))      { полукруг }

Or

((x >= 0) and (y <= 1) and (y >= x-1)) { треугольник }

Then write('принадлежит')

else write('не принадлежит');

Это условие можно немного упростить, заметив, что условие x >= 0 встречается в условиях для обеих областей:

if (x >= 0) and

((x*x + y*y <= 1) or

((y <= 1) and (y >= x-1)))

Then write('принадлежит')

else write('не принадлежит');

 


28) Начнем с заполнения таблицы. Обратите внимание, что второе условие проверяется в приведенной программе только тогда, когда истинно первое, а третье – только тогда, когда истинны первые два. В остальных ячейках (если условие не проверяется) нужно ставить прочерк:

Обл. y<=2-x? y>=0? y>=x*x? вывод верно?
A да да нет
B нет
C да да да
D да да нет
E нет
F нет
G да нет
H нет

Программы выводит какой-то ответ только тогда когда истинны первые два условия; в этом случае ответ зависит от истинности третьего условия:

Обл. y<=2-x? y>=0? y>=x*x? вывод верно?
A да да нет не принадлежит
B нет
C да да да принадлежит
D да да нет не принадлежит
E нет
F нет
G да нет
H нет

Видим, что верно обрабатываются только области А и С, для области D выводится неверный ответ (эта область закрашена, но программа выдает ответ «не принадлежит»), а для остальных никакого ответа не выводится.

Обл. y<=2-x? y>=0? y>=x*x? вывод верно?
A да да нет не принадлежит да
B нет нет
C да да да принадлежит да
D да да нет не принадлежит нет
E нет нет
F нет нет
G да нет нет
H нет нет

Простейший способ исправить ошибку – построить условия для каждой из закрашенных областей, и затем объединить их с помощью операции ИЛИ. Записываем условия для обеих интересующих нас областей (С и D)

C: (y <= 2-x) и (y >= x*x)

D: (y <= 2-x) и (x >= 0) и (y >= 0) и (y <= x*x)

Обратите внимание: легко забыть условие x>=0 для области D!

В этой задаче обе области находятся под прямой y=2-x, поэтому это условие будет общим. Получаем:

C или D: (y <= 2-x) и

                   ((y >= x*x) или (x >= 0) и (y >= 0) и (y <= x*x))                 

Переводим на язык программирования:

if (y<=2-x) and

((y>=x*x) or (x>=0) and (y>=0) and (y<=x*x)) then

Write('принадлежит')

else write('не принадлежит');

Условие можно еще немного упростить:

if (y<=2-x) and (y>=0) and ((x>=0) or (y>=x*x)) then

Write('принадлежит')

else write('не принадлежит');

 

29) Начнем с заполнения таблицы. Обратите внимание, что второе условие проверяется в приведенной программе только тогда, когда истинно первое, а третье – только тогда, когда истинны первые два. В остальных ячейках (если условие не проверяется) нужно ставить прочерк:

Обл. y>=0? y>=2-x? y<=x*x? вывод верно?
A да нет
B да да да
C да нет
D да нет
E да да нет
F да да да
G нет
H нет

Программы выводит какой-то ответ только тогда когда истинны первые два условия; в этом случае ответ зависит от истинности третьего условия:

Обл. y>=0? y>=2-x? y<=x*x? вывод верно?
A да нет
B да да да принадлежит
C да нет
D да нет
E да да нет не принадлежит
F да да да принадлежит
G нет
H нет

Видим, что верно обрабатываются только области B и E, для области F выводится неверный ответ (эта область не закрашена, но программа выдает ответ «принадлежит»), а для остальных никакого ответа не выводится.

Обл. y>=0? y>=2-x? y<=x*x? вывод верно?
A да нет нет
B да да да принадлежит да
C да нет нет
D да нет нет
E да да нет не принадлежит да
F да да да принадлежит нет
G нет нет
H нет нет

Простейший способ исправить ошибку – построить условия для каждой из закрашенных областей, и затем объединить их с помощью операции ИЛИ. Записываем условия для обеих интересующих нас областей (B и D)

B: (y >= 2-x) и (y <= x*x) и (x <= 0)

D: (y <= 2-x) и (x >= 0) и (y >= 0) и (y <= x*x)

Обратите внимание: легко забыть условие x<=0 для области B и условие x>=0 для области D!

В этой задаче обе области находятся под прямой y=2-x, поэтому это условие будет общим. Получаем:

C или D: (y >= 2-x) и (y <= x*x) и (x <= 0) или

                 (y <= 2-x) и (x >= 0) и (y >= 0) и (y <= x*x)                  

Переводим на язык программирования:

if (y >= 2-x) and (y <= x*x) and (x <= 0) or

(y <= 2-x) and (x >= 0) and (y >= 0) and (y <= x*x) then

Write('принадлежит')

else write('не принадлежит');

Условие можно записать и в другом виде:

if (y <= x*x) and (y >= 0) and

((x>=0) and (y<=2-x) or (y>=2-x) and (x<=0)) then

Write('принадлежит')

else write('не принадлежит');

 

30) Это та же самая задача, что и 24, только переформулированная в соответствии с демо-вариантом ЕГЭ-2012. Сразу замечаем, что в программе else относится к последнему оператору if, то есть в самом деле структура кода такова:

if x <= 1 then

if y <= 1 then

if x*x + y*y <= 1 then

Write('принадлежит')

else write('не принадлежит');

Обратите внимание, что второе условие проверяется в приведенной программе только тогда, когда истинно первое, а третье – только тогда, когда истинны первые два. В остальных ячейках (если условие не проверяется) нужно ставить прочерк:

Обл. x<=1 y<=1 x*x+y*y<=1 вывод верно?
A да да да
B да да нет
C да нет -
D нет - -
E да да нет
F нет - -

Программы выводит какой-то ответ только тогда когда истинны первые два условия; в этом случае ответ зависит от истинности третьего условия:

Обл. x<=1 y<=1 x*x+y*y<=1 вывод верно?
A да да да принадлежит
B да да нет не принадлежит
C да нет - -
D нет - - -
E да да нет не принадлежит
F нет - - -

Видим, что верно обрабатываются только области A и B, для области E выводится неверный ответ (эта область не закрашена, но программа выдает ответ «принадлежит»), а для остальных никакого ответа не выводится.

Обл. x<=1 y<=1 x*x+y*y<=1 вывод верно?
A да да да принадлежит да
B да да нет не принадлежит да
C да нет - - нет
D нет - - - нет
E да да нет не принадлежит нет
F нет - - - нет

Для исправления программы лучше всего составить новое сложное условие. Выделенная область может быть получена как объединение двух областей: круга x*x + y*y <= 1 и квадрата с единичной стороной, левый нижний угол которого находится в начале координат:

if (x*x + y*y <= 1) { круг }

Or

((x >= 0) and (x <= 1) and { квадрат}

(y >= 0) and (y <= 1))   

Then write('принадлежит')

else write('не принадлежит');

31) Это та же самая задача, что и 25, только переформулированная в соответствии с демо-вариантом ЕГЭ-2012. Сразу замечаем, что в программе else относится к последнему оператору if, то есть в самом деле структура кода такова:

if y >= 0 then

if x <= 1 then

if y >= x*x then

Write('принадлежит')

else write('не принадлежит');

Обратите внимание, что второе условие проверяется в приведенной программе только тогда, когда истинно первое, а третье – только тогда, когда истинны первые два. В остальных ячейках (если условие не проверяется) нужно ставить прочерк:

Обл. y >= 0 x <= 1 y >= x*x вывод верно?
A да да да
B да нет
C да нет
D да да нет
E да да нет
F нет

Программы выводит какой-то ответ только тогда когда истинны первые два условия; в этом случае ответ зависит от истинности третьего условия:

Обл. y >= 0 x <= 1 y >= x*x вывод верно?
A да да да принадлежит
B да нет
C да нет
D да да нет не принадлежит
E да да нет не принадлежит
F нет

Видим, что верно обрабатываются только области A и D, для области E выводится неверный ответ (эта область закрашена, но программа выдает ответ «не принадлежит»), а для остальных никакого ответа не выводится.

Обл. y >= 0 x <= 1 y >= x*x вывод верно?
A да да да принадлежит да
B да нет нет
C да нет нет
D да да нет не принадлежит да
E да да нет не принадлежит нет
F нет нет

Для исправления программы лучше всего составить новое сложное условие. Выделенная область может быть получена как объединение двух областей: области выше параболы y >= x*xи квадрата с единичной стороной, левый нижний угол которого находится в начале координат:

if ((y >= x*x) and (x <= 1)) { над параболой }

Or

((x >= 0) and (x <= 1) and { квадрат}

(y >= 0) and (y <= 1))   

Then write('принадлежит')

else write('не принадлежит');

Для квадрата ограничение сверху по координате Y несущественно (вся область прямо над квадратом выделена), и можно заменить квадрат на верхнюю часть полосы, убрав последнее условие:

if ((y >= x*x) and (x <= 1)) { над параболой }

Or

((x >= 0) and (x <= 1) and (y >= 0))   

Then write('принадлежит')

else write('не принадлежит');

32) Это та же самая задача, что и 26, только переформулированная в соответствии с демо-вариантом ЕГЭ-2012. Сразу замечаем, что в программе else относится к последнему оператору if, то есть в самом деле структура кода такова:

if x <= 1 then

if y >= 1-x then

if y >= x*x then

Write('принадлежит')

else write('не принадлежит');

Обратите внимание, что второе условие проверяется в приведенной программе только тогда, когда истинно первое, а третье – только тогда, когда истинны первые два. В остальных ячейках (если условие не проверяется) нужно ставить прочерк:

Обл. x <= 1 y >= 1-x y >= x*x вывод верно?
A да да нет
B да да да
C да нет
D да да нет
E нет
F да нет
G нет
H нет

Программы выводит какой-то ответ только тогда когда истинны первые два условия; в этом случае ответ зависит от истинности третьего условия:

Обл. x <= 1 y >= 1-x y >= x*x вывод верно?
A да да нет не принадлежит
B да да да принадлежит
C да нет
D да да нет не принадлежит
E нет
F да нет
G нет
H нет

Видим, что верно обрабатываются только областей А и В, для области D выводится неверный ответ (эта область закрашена, но программа выдает ответ «не принадлежит»), а для остальных никакого ответа не выводится.

Обл. x <= 1 y >= 1-x y >= x*x вывод верно?
A да да нет не принадлежит да
B да да да принадлежит да
C да нет нет
D да да нет не принадлежит нет
E нет нет
F да нет нет
G нет нет
H нет нет

Для исправления программы лучше всего составить новое сложное условие. Выделенная область может быть получена как объединение двух областей: области B выше параболы y >= x*x и линии y = 1-x и (одновременно) слева от прямой x = 1, и верхней части полосы 0<=x<=1, которая снизу ограничена линией y = 1-x:

if ((y >= x*x) and (y >= 1-x) and (x <= 1)) 

{ синяя область над параболой и прямой }

Or

((x >= 0) and (x <= 1) and (y >= 1-x)) { полоса над прямой }

Then write('принадлежит')

else write('не принадлежит');

Это условие можно немного упростить, заметив, что условия y >= 1-x и x <= 1 встречаются в условиях для обеих областей:

if (y >= 1-x) and { над прямой }

(x <= 1) and { слева от прямой x = 1} 

   ((y >= x*x) or { выше параболы }

    (x >= 0)) { справа от прямой x = 0 } 

Then write('принадлежит')

else write('не принадлежит');


33) Это та же самая задача, что и 27, только переформулированная в соответствии с демо-вариантом ЕГЭ-2012. Сразу замечаем, что в программе else относится к последнему оператору if, то есть в самом деле структура кода такова:

if x >= 0 then

if y <= 1 then

if (x*x + y*y <= 1) and (y >= x-1)

Then

Write('принадлежит')

else write('не принадлежит');

Обратите внимание, что второе условие проверяется в приведенной программе только тогда, когда истинно первое, а третье – только тогда, когда истинны первые два. В остальных ячейках (если условие не проверяется) нужно ставить прочерк:

Обл. x >= 0 y <= 1 (x*x+y*y<=1) and (y>=x-1) вывод верно?
A да да да
B да да нет
C нет
D нет
E да да нет
F да да нет
G нет
H да нет
J да нет
K нет

Программы выводит какой-то ответ только тогда когда истинны первые два условия; в этом случае ответ зависит от истинности третьего условия:

Обл. x >= 0 y <= 1 (x*x+y*y<=1) and (y>=x-1) вывод верно?
A да да да принадлежит
B да да нет не принадлежит
C нет
D нет
E да да нет не принадлежит
F да да нет не принадлежит
G нет
H да нет
J да нет
K нет

Видим, что верно обрабатываются только областей А и E, для областей B и F выводится неверный ответ (эти области закрашены, но программа выдает ответ «не принадлежит»), а для остальных никакого ответа не выводится.

Обл. x >= 0 y <= 1 (x*x+y*y<=1) and (y>=x-1) вывод верно?
A да да да принадлежит да
B да да нет не принадлежит нет
C нет нет
D нет нет
E да да нет не принадлежит да
F да да нет не принадлежит нет
G нет нет
H да нет нет
J да нет нет
K нет нет

Для исправления программы лучше всего составить новое сложное условие. Выделенная область может быть получена как объединение двух областей: полукруга

(x >= 0) and (x*x + y*y <= 1)

и треугольника

(x >= 0) and (y <= 1) and (y >= x-1)

Получаем:

if ((x >= 0) and (x*x + y*y <= 1))   { полукруг }

Or

((x >= 0) and (y <= 1) and (y >= x-1)) { треугольник }

Then write('принадлежит')

else write('не принадлежит');

Это условие можно немного упростить, заметив, что условие x >= 0 встречается в условиях для обеих областей:

if (x >= 0) and

((x*x + y*y <= 1) or

((y <= 1) and (y >= x-1)))

Then write('принадлежит')

else write('не принадлежит');

34) Сразу замечаем, что в программе else относится к последнему оператору if, то есть в самом деле структура кода такова:

if y <= 3-x*x then

if y >= 0 then

if y >= x+1 then

Write('принадлежит')

Else

write('не принадлежит');

Обратите внимание, что второе условие проверяется в приведенной программе только тогда, когда истинно первое, а третье – только тогда, когда истинны первые два. В остальных ячейках (если условие не проверяется) нужно ставить прочерк:

Обл. y <= 3-x*x y >= 0 y >= x+1 вывод верно?
A нет
B нет
C да нет
D да нет
E да да нет
F да да да
G да да да
H да да нет
J нет
K нет

Программы выводит какой-то ответ только тогда когда истинны первые два условия; в этом случае ответ зависит от истинности третьего условия:

Обл. y <= 3-x*x y >= 0 y >= x+1 вывод верно?
A нет
B нет
C да нет
D да нет
E да да нет не принадлежит
F да да да принадлежит
G да да да принадлежит
H да да нет не принадлежит
J нет
K нет

Видим, что верно обрабатываются только областей E, F и G, для области H выводится неверный ответ (она закрашена, но программа выдает ответ «не принадлежит»), а для остальных никакого ответа не выводится.

Обл. y <= 3-x*x y >= 0 y >= x+1 вывод верно?
A нет нет
B нет нет
C да нет нет
D да нет нет
E да да нет не принадлежит да
F да да да принадлежит да
G да да да принадлежит да
H да да нет не принадлежит нет
J нет нет
K нет нет

Для исправления программы лучше всего составить новое сложное условие. Во-первых, вся выделенная область находится ниже параболы, поэтому условие имеет вид

(y <= 3-x*x) and (...)

где вместо многоточия нужно добавить некоторое условие. Закрашенная область может быть получена объединением двух областей: выше прямой (y>=x+1) и в первом квадранте ((x>=0) and (y>=0)). Эти две области объединяются с помощью логической операции ИЛИ (or). Таким образом, получаем

if (y <= 3-x*x) and

((y >= x+1) or  { выше прямой }

(x>=0) and (y>=0)) { первый квадрант }         

Then write('принадлежит')

else write('не принадлежит');

35) Сразу замечаем, что в программе else относится к последнему оператору if.Обратите внимание, что второе условие проверяется в приведенной программе только тогда, когда истинно первое, а третье – только тогда, когда истинны первые два. В остальных ячейках (если условие не проверяется) нужно ставить прочерк:

Область Условие 1 (x>1) Условие 2 (х>=7) Условие 3 (х>13) Программа выведет Область обрабатывается верно
А нет
В нет
С да нет
D да да нет
Е да да да

Программы выводит какой-то ответ только тогда когда истинны первые два условия; в этом случае ответ зависит от истинности третьего условия:

Область Условие 1 (x>1) Условие 2 (х>=7) Условие 3 (х>13) Программа выведет Область обрабатывается верно
А нет нет
В нет нет
С да нет нет
D да да нет принадлежит да
Е да да да не принадлежит да

Нужная область представляет собой объединение двух областей, которые описываются двойными неравенствами

-5 <= x <= 1 и 7 <= x <= 13

Поскольку в Паскале двойные неравенства использовать нельзя (а в некоторых языках, например, в школьном алгоритмическом языке системы КуМир – можно!), заменяем их на сложные условия с логической операцией «И» (and):

(-5 <= x) and (x <= 1)

(7 <= x) and (x <= 13)

Для объединения областей два эти условия нужно объединить с помощью логической операции «ИЛИ» (or). Таким образом, получаем такое решение:

if (-5 <= x) and (x <= 1) or

(7 <= x) and (x <= 13) then

Write('принадлежит')

else write('не принадлежит');

Здесь учтено, что логическая операция «ИЛИ» имеет более низкий приоритет, чем «И», и поэтому выполняется последней.

36) Эта задача полностью аналогична задача 35, поэтому приведем сразу ответ. Заполненная таблица:

Область Условие 1 (x<=15) Условие 2 (х<9) Условие 3 (х<=3) Программа выведет Область обрабатывается верно
А да да да принадлежит нет
В да да да принадлежит да
С да да нет не принадлежит да
D да нет нет
Е нет нет

Исправленная программа на Паскале:

if (-3 <= x) and (x <= 3) or

(9 <= x) and (x <= 15) then

Write('принадлежит')

else write('не принадлежит');

37) Эта задача полностью аналогична задача 35, поэтому приведем сразу ответ. Заполненная таблица:

Область Условие 1 (x<=14) Условие 2 (х>=-4) Условие 3 (х>=8) Программа выведет Область обрабатывается верно
А да нет нет
В да да нет не принадлежит нет
С да да нет не принадлежит да
D да да да принадлежит да
Е нет нет

Исправленная программа на Паскале:

if (-4 <= x) and (x <= 2) or

(8 <= x) and (x <= 14) then

write('принадлежит')

else write('не принадлежит');

38) В приведённой программе блок else относится к последнему (вложенному) условному оператору. Обратите внимание, что второе условие проверяется в приведенной программе только тогда, когда истинно первое, а третье – только тогда, когда истинны первые два. В остальных ячейках (если условие не проверяется) нужно ставить прочерк:

Обл. y >= x*x-2 y <= 4-x*x x >= 0 вывод верно?
A да нет
B нет
C да да нет
D да да нет
E да да да
F да да да
G нет
H нет

Программы выводит какой-то ответ только тогда когда истинны первые два условия; в этом случае ответ зависит от истинности третьего условия:

Обл. y >= x*x-2 y <= 4-x*x x >= 0 вывод верно?
A да нет
B нет
C да да нет не принадлежит
D да да нет не принадлежит
E да да да принадлежит
F да да да принадлежит
G нет
H нет

Видим, что верно обрабатываются только областей E, F и G, для области H выводится неверный ответ (она закрашена, но программа выдает ответ «не принадлежит»), а для остальных никакого ответа не выводится.

Обл. y >= x*x-2 y <= 4-x*x x >= 0 вывод верно?
A да нет нет
B нет нет
C да да нет не принадлежит нет
D да да нет не принадлежит да
E да да да принадлежит да
F да да да принадлежит да
G нет нет
H нет нет

Для исправления программы лучше всего составить новое сложное условие. Во-первых, вся выделенная область находится ниже параболы , поэтому условие имеет вид

(y <= 4-x*x) and (...)

где вместо многоточия нужно добавить некоторое условие. Закрашенная область может быть получена объединением двух областей: между параболами справа от оси OY ((x>=0) and (y>=x*x-2)) и во втором квадранте ((x<=0) and (y>=0)). Эти две области объединяются с помощью логической операции ИЛИ (or). Таким образом, получаем

if (y<=4-x*x) and

((x>=0) and (y>=x*x-2) { между параболами справа от OY }

 or (x<=0) and (y>=0)) { второй квадрант }

Then write('принадлежит')

else write('не принадлежит');

39) Эта задача похожа на задачи 35-37, только здесь три интервала:

В приведённой программе блок else относится к последнему (вложенному) условному оператору. Обратите внимание, что второе условие проверяется в приведенной программе только тогда, когда истинно первое, а третье – только тогда, когда истинны первые два. В остальных ячейках (если условие не проверяется) нужно ставить прочерк[2]:

Область Условие 1 (x>=-5 or x<=1) Условие 2 (x>=-3 and x<=3) Условие 3 (х>=-1 and x<=5) Программа выведет Область обрабатывается верно
А да нет нет
В да нет нет
С да да нет не принадлежит да
D да да да принадлежит да
Е да да да принадлежит нет
F да нет нет
G да нет нет

Видим, что верно обрабатываются только областей C и D, для области E выводится неверный ответ (она не заштрихована, но программа выдает ответ «принадлежит»), а для остальных никакого ответа не выводится.

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

(x принадлежит [-5, -3]) или

(x принадлежит [-1, 1]) или

(x принадлежит [3, 5])

В переводе на Паскаль:

if (-5 <= x) and (x <= -3) or

(-1 <= x) and (x <= 1) or

(3 <= x) and (x <= 5) then

Write('принадлежит')

else write('не принадлежит');

40) Эта традиционная задача с областями имеет существенные отличия в условии. Во-первых, пугает большое количество областей, но при дальнейшем чтении условия выясняется, что заполнять таблицу для всех этих областей не нужно.

В приведённой программе блок else относится к последнему (вложенному) условному оператору. Обратите внимание, что второе условие проверяется в приведенной программе только тогда, когда истинно первое, а третье – только тогда, когда истинны первые два.

Итак, дана таблица (для улдобства к ней слева добавлен столбец с нумерацией строк):

Область Условие 1 (х*х + у*у <= 25) Условие 2 (у <= 4-х*х) Условие 3(y <= х+1) Вывод Верно
1   да      
2         принадлежит нет
3       нет   нет

Посмотрим на строку 2: поскольку выдан ответ «принадлежит», выполнены все три условия, но это ответ неверный, то есть область (или области), соответствующие второй строке, не заштрихованы. Итак, эта область внутри круга (условие 1), под параболой (условие 2) и ниже прямой (условие 3). Кроме того, она не заштрихована. Этим четырём условиям соответствует тольбко область R.

Область Условие 1 (х*х + у*у <= 25) Условие 2 (у <= 4-х*х) Условие 3(y <= х+1) Вывод Верно
1   да      
2 R да да да принадлежит нет
3       нет   нет

Теперь смотрим на третью строку. Третье условие проверялось, поэтому первые два условия были выполнены (для них ставим ответ «да»). Третье не выполнено, поэтому будет выдан ответ «не принадлежит». Но этот ответ неверный, то есть на самом деле область заштрихована! Итак, эта область внутри круга (условие 1), под параболой (условие 2) и выше прямой (условие 3 не выполнено). Кроме того, она заштрихована. Этим четырём условиям соответствует только область G.

 

Область Условие 1 (х*х + у*у <= 25) Условие 2 (у <= 4-х*х) Условие 3(y <= х+1) Вывод Верно
1   да      
2 R да да да принадлежит нет
3 G да да нет не принадлежит нет

Осталось разобраться с первой строкой. Поскольку ничего не было выведено, третье условие не проверялось, поэтому второе оказалось ложно. Ответ явно неверный (нет ответа). Итак, эта область внутри круга (условие 1) и над параболой (условие 2 ложно). Этим двум условиям соответствуют области D, K, M, P, S (согласно текущим правилам оценивания, можно указать любй набор из этого множества и даже одну букву):

Область Условие 1 (х*х + у*у <= 25) Условие 2 (у <= 4-х*х) Условие 3(y <= х+1) Вывод Верно
1 D, K, M, P, S да нет нет
2 R да да да принадлежит нет
3 G да да нет не принадлежит нет

Для того, чтобы написать правильную программу, проще всего составить одно сложное условие. Области G и H находятся под параболой в первом координатном углу, что соответствует условию

(x >= 0) and (y >= 0) and (y <=4-x*x)

Остальные выделенные области (F, P, Q) входят в «сектор», образованный осью OY, прямой y=x+1 и окружностью, что соответсвует условию

(x <= 0) and (y <= x+1) and (x*x+y*y<=25)

Два записанных сложных условия нужно объединить с помощью операции ИЛИ (or).

if (x >= 0) and (y >= 0) and (y <=4-x*x)

Or

(x <= 0) and (y <= x+1) and (x*x+y*y<=25)

Then

Write('принадлежит')

else write('не принадлежит');

41) Эта задача по структуре аналогична задаче 40. Рассмотрим таблицу, в которую добавлена нумерация строк:

Область Условие 1 (y >= x*x-6) Условие 2 (x*x+y*y <= 16) Условие 3 (x >= 0) Вывод Верно
1   да      
2         принадлежит нет
3         не принадлежит да
4         да

Напомним программу:

if у >= x*x-6 then begin

if x*x + у* у <=16 then

Write('принадлежит')

End

Else

if x >= 0 then

Write('принадлежит')

Else write('не принадлежит')

В строке 1 ничего не выводится, значит ответ неверный. Кроме того, поскольку первое условие верно и вывода нет, второе не выполняется, а третье вообще не проверяется. То есть, эта область расположена выше параболы, но вне круга; это могут быть область B, C, Q, R:

Область Условие 1 (y >= x*x-6) Условие 2 (x*x+y*y <= 16) Условие 3 (x >= 0) Вывод Верно
1 B, C, Q, R да нет нет
2         принадлежит нет
3         не принадлежит да
4         да

Теперь рассмотрим строку 2. Программа выдает ответ «принадлежит», что может быть

1. при выполнении первых двух условий (точки выше параболы и внутри круга) или

2. если первое условие на выполняется (точки ниже параболы), а третье – выполняется (точки справа от оси OY).

При этом ответ «принадлежит» неверный. Поскольку ВСЕ точки, для которых выполняются первые два условия, принадлежат заштрихованной области, первый вариант исключается. Поэтому для второй строки первое условие ложно (точки ниже параболы), второе не проверяется, а третье – истинно (точки справа от оси OY); эти области не заштрихованы, поэтому это могут быть только области D и S:

Область Условие 1 (y >= x*x-6) Условие 2 (x*x+y*y <= 16) Условие 3 (x >= 0) Вывод Верно
1 B, C, Q, R да нет нет
2 D, S нет да принадлежит нет
3         не принадлежит да
4         да

Третья строка. Сообщение «не принадлежит» выводится для точек, которые ниже параболы и слева от оси OY, эти точки не принадлежат выделенной области; это могут быть области A, E, K, P.

Область Условие 1 (y >= x*x-6) Условие 2 (x*x+y*y <= 16) Условие 3 (x >= 0) Вывод Верно
1 B, C, Q, R да нет нет
2 D, S нет да принадлежит нет
3 A, E, K, P нет нет не принадлежит да
4         да

Наконец, для четвертой строки третье условие не проверяется, значит, первое истинно. Второе проверяется, и результат верный. Это значит, что второе условие истинно и выведено сообщение «принадлежит». Это точки, расположенные выше параболы и внутри круга, то есть области F, G, L и M.

Область Условие 1 (y >= x*x-6) Условие 2 (x*x+y*y <= 16) Условие 3 (x >= 0) Вывод Верно
1 B, C, Q, R да нет нет
2 D, S нет да принадлежит нет
3 A, E, K, P нет нет не принадлежит да
4 F, G, L, M да да принадлежит да

Для того, чтобы написать правильную программу, составим одно сложное условие. Проще всего сложить полную область из трех:

1. область внутри круга и выше параболы:

(y>=x*x-6) and (x*x+y*y<=16)

2. область выше параболы и ниже оси OX: (y>=x*x-6) and (y<=0)

3. правый полукруг: (x*x+y*y<=16) and (x>=0)

Остается объединить эти области с помощью операции ИЛИ:

if (y>=x*x-6) and (x*x+y*y<=16) or

(y>=x*x-6) and (y=<0) or

(x*x+y*y<=16) and (x>=0)

Then write('принадлежит')

else write('не принадлежит');

42) Рассмотрим таблицу, в которую добавлена нумерация строк:

Область Условие 1 (y >= 1-x) Условие 2 (y <= 2-2*x*x) Условие 3 (y >= x*x-5) Вывод Верно
1          
2         принадлежит нет
3         не принадлежит да
4         да

Напомним программу:

if y >= 1-x then begin

if y <= 2-2*x*x then    

Write('принадлежит')

End

Else

if y >= x*x-5 then

Write('принадлежит')

Else write('не принадлежит')

В строке 1 ничего не выводится, значит ответ неверный. Такой вариант (отсутствие вывода) говорит о том, что первое условие выполнено, а второе – нет. То есть, эта область расположена выше прямой и  выше параболы y = 2 - 2x2; это могут быть область B, C, D, N, P:

Область Условие 1 (y >= 1-x) Условие 2 (y <= 2-2*x*x) Условие 3 (y >= x*x-5) Вывод Верно
1 B, C, D, N, P да нет нет
2         принадлежит нет
3         не принадлежит да
4         да

Теперь рассмотрим строку 2. Программа выдает ответ «принадлежит», что может быть

1. при выполнении первых двух условий (точки выше прямой и ниже параболы y = 2 - 2x2) или

2. если первое условие на выполняется (точки ниже прямой), а третье – выполняется (точки выше параболы y = x2 - 5).

При этом ответ «принадлежит» неверный. Поскольку ВСЕ точки, для которых выполняются первые два условия, принадлежат заштрихованной области G, первый вариант исключается. Поэтому для второй строки первое условие ложно (точки ниже прямой), второе не проверяется, а третье – истинно (точки выше параболы y = x2 - 5); эти области не заштрихованы, поэтому это могут быть только области K и L:

Область Условие 1 (y >= 1-x) Условие 2 (y <= 2-2*x*x) Условие 3 (y >= x*x-5) Вывод Верно
1 B, C, D, N, P да нет нет
2 K, L нет да принадлежит нет
3         не принадлежит да
4         да

 

Третья строка. Сообщение «не принадлежит» выводится для точек, которые ниже прямой и ниже параболы y = x2 - 5, эти точки не принадлежат выделенной области; это могут быть области A, H, Q, R.

Область Условие 1 (y >= 1-x) Условие 2 (y <= 2-2*x*x) Условие 3 (y >= x*x-5) Вывод Верно
1 B, C, D, N, P да нет нет
2 K, L нет да принадлежит нет
3 A, H, Q, R нет нет не принадлежит да
4         да

Наконец, для четвертой строки третье условие не проверяется, значит, первое истинно. Второе проверяется, и результат верный. Это значит, что второе условие истинно и выведено сообщение «принадлежит». Это точки, расположенные выше прямой и ниже параболы y = 2 - 2x2, то есть область G.

Область Условие 1 (y >= 1-x) Условие 2 (y <= 2-2*x*x) Условие 3 (y >= x*x-5) Вывод Верно
1 B, C, D, N, P да нет нет
2 K, L нет да принадлежит нет
3 A, H, Q, R нет нет не принадлежит да
4 G да да принадлежит да

Для того, чтобы написать правильную программу, составим одно сложное условие. Проще всего сложить полную область из трех:

1. область G:             (y >= 1-x) and (y <= 2-2*x*x)

2. области E и F:       (y <= 1-x) and (y >= 0) and (y >= x*x-5)

3. область M:            (y <= 1-x) and (y >= 2-2*x*x) and (y >= x*x-5)

 and (x >= 0)

Остается объединить эти области с помощью операции ИЛИ:

if (y >= 1-x) and (y < 2-2*x*x) or

(y <= 1-x) and (y >= 0) and (y >= x*x-5) or

(y <= 1-x) and (y >= 2-2*x*x) and (y >= x*x-5)

and (x >= 0)

Then write('принадлежит')

else write('не принадлежит');

Возможен и более хитрый способ:

1. области F и G:      (y >= 0) and (y <= 2-2*x*x)

2. область E и часть области F:            

                 (y <= 1-x) and (y >= x*x-5) and (y >= 2-2*x*x)

              and (x<=0) and (y>=0)

3. область M: (y <= 1-x) and (y >= x*x-5) and (y >= 2-2*x*x)

              and (x>=0) and (y<=0)

Два условия, выделенные синим цветом, можно записать в виде (x*y<=0). Поэтому условие для областей 2 и 3 переписываем в виде

(y <= 1-x) and (y >= 2-2*x*x) and (y >= x*x-5) and (x*y <= 0)

Получаем:

if (y >= 0) and (y <= 2-2*x*x) or

(y <= 1-x) and (y >= 2-2*x*x) and (y >= x*x-5)

         and (x*y <= 0)

Then write('принадлежит')

else write('не принадлежит');

43) Рассмотрим таблицу, в которую добавлена нумерация строк:

Область Условие 1 (y >= x+1) Условие 2 (y <= 2-2*x*x) Условие 3 (y >= x*x-5) Вывод Верно
1          
2         принадлежит нет
3         не принадлежит да
4         да

Напомним программу:

if y >= x+1 then begin

if y <= 2-2*x*x then    

Write('принадлежит')

End

Else

if y >= x*x-5 then

Write('принадлежит')

Else write('не принадлежит')

В строке 1 ничего не выводится, значит ответ неверный. Такой вариант (отсутствие вывода) говорит о том, что первое условие выполнено, а второе – нет. То есть, эта область расположена выше прямой и выше параболы y = 2 - 2x2; это могут быть область A, B, C, H, K:

Область Условие 1 (y >= x+1) Условие 2 (y <= 2-2*x*x) Условие 3 (y >= x*x-5) Вывод Верно
1 A, B, C, H, K да нет нет
2         принадлежит нет
3         не принадлежит да
4         да

Теперь рассмотрим строку 2. Программа выдает ответ «принадлежит», что может быть

1. при выполнении первых двух условий (точки выше прямой и ниже параболы y = 2 - 2x2) или

2. если первое условие на выполняется (точки ниже прямой), а третье – выполняется (точки выше параболы y = x2 - 5).

При этом ответ «принадлежит» неверный. Поскольку ВСЕ точки, для которых выполняются первые два условия, принадлежат заштрихованной области D, первый вариант исключается. Поэтому для второй строки первое условие ложно (точки ниже прямой), второе не проверяется, а третье – истинно (точки выше параболы y = x2 - 5); эти области не заштрихованы, поэтому это могут быть только области M и N:

Область Условие 1 (y >= x+1) Условие 2 (y <= 2-2*x*x) Условие 3 (y >= x*x-5) Вывод Верно
1 A, B, C, H, K да нет нет
2 M. N нет да принадлежит нет
3         не принадлежит да
4         да

Третья строка. Сообщение «не принадлежит» выводится для точек, которые ниже прямой и ниже параболы y = x2 - 5, эти точки не принадлежат выделенной области; это могут быть области G, P, Q, R.

Область Условие 1 (y >= x+1) Условие 2 (y <= 2-2*x*x) Условие 3 (y >= x*x-5) Вывод Верно
1 A, B, C, H, K да нет нет
2 M. N нет да принадлежит нет
3 G, P, Q, R нет нет не принадлежит да
4         да

Наконец, для четвертой строки третье условие не проверяется, значит, первое истинно. Второе проверяется, и результат верный. Это значит, что второе условие истинно и выведено сообщение «принадлежит». Это точки, расположенные выше прямой и ниже параболы y = 2 - 2x2, то есть область D.

Область Условие 1 (y >= x+1) Условие 2 (y <= 2-2*x*x) Условие 3 (y >= x*x-5) Вывод Верно
1 A, B, C, H, K да нет нет
2 M. N нет да принадлежит нет
3 G, P, Q, R нет нет не принадлежит да
4 D да да принадлежит да

Для того, чтобы написать правильную программу, составим одно сложное условие. Проще всего сложить полную область из трех:

1. область D:              (y >= x+1) and (y < 2-2*x*x)

2. области E и F:       (y <= x+1) and (y >= 0) and (y >= x*x-5)

3. область L:               (y <= x+1) and (y >= 2-2*x*x) and (y >= x*x-5)

       and (x <= 0)

Остается объединить эти области с помощью операции ИЛИ:

if (y >= x+1) and (y <= 2-2*x*x) or

(y <= x+1) and (y >= 0) and (y >= x*x-5) or

(y <= x+1) and (y >= 2-2*x*x) and (y >= x*x-5)

       and (x <= 0)

Then write('принадлежит')

else write('не принадлежит');

Более хитрый способ:

1. области D и E:      (y >= 0) and (y <= 2-2*x*x)

2. область F и часть области E:            

         (y <= x+1) and (y >= 2-2*x*x) and (y >= x*x-5)

           and (x>=0) and (y>=0)

3. область L: (y <= x+1) and (y >= 2-2*x*x) and (y >= x*x-5)

              and (x<=0) and (y<=0)

Два условия, выделенные синим цветом, можно записать в виде (x*y>=0). Поэтому условие для областей 2 и 3 переписываем в виде

(y <= x+1) and (y >= 2-2*x*x) and (y >= x*x-5) and (x*y >= 0)

Получаем:

if (y >= 0) and (y <= 2-2*x*x) or

(y <= x+1) and (y >= 2-2*x*x) and (y >= x*x-5)

         and (x*y <= 0)

Then write('принадлежит')

else write('не принадлежит');

44) Сначала выполним первое задание, подставив значения n = 5, a = 3, b = 6 в программу:

if a + b < n then writeln(0)

Else

if a < b then

if a < n then writeln(a+1)

Else

    if b < n then writeln(b+1)

 else writeln(n+1);

Выделив структуру заданой программы получаем 4 вложенных условия. Для заданных исходных данных первое условие a + b < n = 3 + 6 < 5 ложно, второе a < b = 3 < 6 истинно, третье
a < n = 3 < 5 истинно, поэтому программа выведет значение a + 1 = 3 + 1 = 4.

Для того, чтобы ответить на второй вопрос, заметим, что программа ничего не выводит, если первое условие ложно, и второе тоже ложно. Например, это может быть при n = 5, a = 6, b = 3.

Теперь нужно разобраться, какое решение является правильным. Представим модель задачи в виде трёх лент длиной a, b и n. Ленты длиной a, b соеднены вместе, а лента длиной n двигается относительно границы между первыми двумя, но так, чтобы не выйти за границы соединённой полосы «a+b». Варианты, которые нам нужно подсчитать, отличаются только положением границы, обозначенной красной линией.

Очевидно, что при a+b<n число вариантов равно 0, то есть, первое условие исходной программы верно.

Если a ≥ n, то все вынутые шары могут быть красными (1 вариант), кроме того, ленту длиной n можно сдвинуть вправо на min(b,n) вправо, поэтому для этого случая

if a >= n then

if b < n then writeln(b+1)

else     writeln(n+1);

Теперь разберем второй вариант, когда a < n.

В этом случае есть 1 вариант, когда количество красных шаров равно a, и ленту ленту длиной n можно сдвинуть вправо на

min(a+b-n,a) = a + min(b-n,0)= a - n + min(b,n)

вправо, поэтому для этого случая имеем

if a < n then

if b < n then writeln(a+b-n+1)

else     writeln(a+1);

Окончательный вариант доработки сложного условия:

if a + b < n then writeln (0)

Else

if a >= n then

if b < n then writeln(b+1)

else     writeln(n+1)

Else

if b < n then writeln(a+b-n+1)

else     writeln(a+1);

Можно сделать и по-другому:

if a + b < n then writeln (0)

Else

if (a < n) and (b < n) then

writeln (a+b-n+1)

Else

if (a >= n) and (b >= n) then

writeln (n+1)

Else

if (a >= n) then writeln (b+1)

else        writeln (a+1);

45) Сначала выполним первое задание, подставив значение N = 532 в программу:

var N, product: longint;

digit: integer;

Begin

readln(N);

product := N mod 10;

while N >= 10 do begin

digit := N mod 10;

product := product * digit;

N := N div 10

end;

Writeln ( product )

End.

Составим таблцу изменения переменных:

оператор N digit product
? ? ?
readln(N); 532
product := N mod 10; 2
N >= 10?

да

digit := N mod 10; 2
product := product * digit; 4
N := N div 10 53
N >= 10?

да

digit := N mod 10; 3
product := product * digit; 12
N := N div 10 5
N >= 10?

нет

writeln ( product ) 12

Из таблицы видим, что

1. При вводе числа 532 программа выдает 12, это ответ на первый вопрос.

2. Программа работает неверно, то есть, неправильно вычисляет произведеие цифр.

Теперь разберёмся, в чём проблема. Во-первых, из таблицы видим, что последняя цифра 2 дважды вошла в произведение: один раз – до цикла, в результате присваивания начального значения переменной product, а второй раз – на первом шаге цикла. Чтобы снять эту проблему нужно до цикла присвоить переменной product начальное значение 1 (это типичное начальное значение переменной при накоплении произведения, при суммировании обычно используют 0).

Во-вторых, самая старшая цифра, 5, не вошла в произведение, потому что цикл остановился раньше времени. Чтобы этого не происходило, нужно написать условие цикла, при котором он останавливается только тогда, когда все цифры рассмотрены (отброшены) и в переменной N осталось значение 0.

Таким образом, ответ на второй вопрос вылядит так:

Ошибка 1:

а) строка перед циклом product := N mod 10;

б) исправление: product := 1;

Ошибка 2:

а) заголовок цикла while N >= 10 do begin

б) исправление: while N > 0 do begin

46) Эта задача полностью аналогична задаче 45. На самом деле, приведённая программа выводит наибольшую цифру введённого числа.

Приведем сразу ответ:

1) при вводе числа 532 программа выводит 5.

2) Ошибка 1: начальное значение переменной min_digit

строка: min_digit := 0;

исправление: min_digit := 9; (любое значение, большее или равное 9)

Ошибка 2: условие изменения переменной min_digit

строка: if digit > min_digit then

исправление: if digit < min_digit then

47) Эта задача аналогична задаче 45.

Приведем сразу ответ:

1) при вводе числа 123 программа выводит 3 (правильный ответ).

2) программа работает неверно для любого числа, у которого старшая цифра больше 1, например, для числа 232

3) Ошибка 1: начальное значение переменной count

строка: count:= 1;

исправление: count:= 0;

Ошибка 2: условие в заголовке цикла

строка: while N > 1 do begin

исправление: while N > 0 do begin

48) Рассмотрим цикл, приведенный в программе:

while n>10 do begin

n := n mod 10

end;

Поскольку цикл начинает работать только при n > 10, при всех значениях n <= 10 (в том числе и для n = 10) будет выведено исходное число. Таким образом, только из-за строгого неравенства в условии цикла программа неверно работает для n = 10 (выдаёт 10 вместо 1).

Если условие в заголовке цикла выполнено, то на первом же шаге в переменную n будет записана последняя цифра этого числа (0..9) и цикл сразу закончится, потому что условие n > 10 уже не будет выполняться. Таким образом, для чисел, больших 10, программы выдаёт последнюю цифру, а не первую. Для того, чтобы получить первую цифру, нужно на каждом шаге отсекать последнюю цифру с помощью целочисленного деления на 10 (n div 10).

1) при вводе числа 1984 программа выводит 4 (неправильный ответ).

2) программа работает верно для любого числа, у которого старшая цифра равна младшей, в том числе для любого однозначного числа

3) Ошибка 1: в условии цикла должно быть нестрогоге равенство:

строка: while n>10 do begin

исправление: while n>=10 do begin

Ошибка 2: операция в теле цикла

строка: n := n mod 10

исправление: n := n div 10

49) Во–первых, найдем, где программа формирует результат, что есть, что она выводит:

writeln(T);

Теперь посмотрим, как строится T:

T:=1;

while N>0 do begin

d := N mod 10;

if d<>1 then begin

R := R + d*T;

T := T+1

end;

N := N div 10;

end;

Алгоритм работы

while N>0 do begin

...

N := N div 10;

end;

говорит о том, что мы последовательно отсекаем от N последние цифры, пока это значение не станет равно 0. Значение этой последней цифры перед отсечением сохраняется в переменной d:

d := N mod 10;

Смотрим, что происходит, если эта цифра не равна 1:

R:=0;

T:=1;

... 

if d<>1 then begin

R := R + d*T;

T := T+1

end;

Судя по этой программе, результат накапливается в переменной R, а T служит счётчиком. Поскольку счётчик начинает отсчёт с 1 увеличивается с каждой неединичной цифрой, в конце работы программа он будет на 1 больше, чем количество цифр, отличных от 1. Таким образом, для входного значения 314, в котором 2 цифры, отличные от 1, программа выведет 3.

Если наша гипотеза верна, то выводить нужно число R, а не T, это первая ошибка.

Далее, для добавления очередного СТАРШЕГО разряда к числу R нужно умножать d не на счётчик, а на 10k, где k – номер разряда, то есть с каждым шагом значение T должно увеличиваться в 10 раз, а не на 1. Это вторая ошибка.

1) при вводе числа 314 программа выводит 3 (неправильный ответ).

2) Ошибка 1: выводить следует значение переменной R:

строка: writeln(T);

исправление: writeln(R);

Ошибка 2: изменение переменной T в теле цикла

строка: T := T+1

исправление: T := T*10

50) Во–первых, найдем, где программа формирует результат, то есть, что она выводит:

writeln(m);

Теперь посмотрим, как строится m:

m := 0;

while n>=1 do begin

d := n mod 10;

if d > 1 then begin

m := 10*d + m;

end;

n:= (n – d) div 10;

end;

Итак, m зависит только от значений d, получаемых на каждом шаге цикла:

d := n mod 10;

Очевидно, что это последняя цифра в десятичной записи числа. Попробуем применить этот алгоритм к «хорошему» числу 23, оно не содержит ни нулей, ни единиц, мы должны получить 32. Фактически будет так:

n d m
23   0
  3 30
2 2 50

Итак, цифры (в переменной d) выделяются правильно, а результат строится неправильно. Фактически программа складывает цифры, умноженные на 10. Это происходит только для тех цифр, которые больше 1, поэтому программа находит сумму цифр, не равных 1, умноженную на 10. Для числа 1984 она выдаст число (9+8+4)*10 = 210.

Достаточно сложен второй вопрос: для каких чисел программа выдаст верный результат? Итак, сумма цифр (кроме 1), умноженная на 10, должна быть равна числу, «развёрнутому» наоборот, без единиц. Значит, в числе обязательно должен быть ноль, причём он должен быть самой старшей цифрой, если отбросить все единицы. Очевидно, что тогда старшая цифра исходного числа – единица, причем единиц впереди может быть много. Пусть в числе есть одна неединичная цифра 2 (отличная от 0), тогда подходят числа 102, 1012, 1102 и т.п. Это ответ на второй вопрос.

Итак, одну ошибку мы нашли, она в строке

m := 10*d + m;

Для того, чтобы исправить эту ошибку, нужно поменять m и d в правой части:

m := 10*m + d;

Проверим, что это на самом деле верно:

n d m
23   0
  3 3
2 2 32

Число было действительно «развёрнуто». Однако это не всё, у нас есть ещё одна «подозрительная» цифра, 0. При проверке получаем, что нули тоже отсекаются условным оператором и не включаются в результат, что неверно:

n d m
203   0
  3 3
20 0  
2 2 32

Это значит, что неверное условие

if d > 1 then ...

его нужно заменить так, чтобы отсекать только единицы:

if d <> 1 then ...

1) при вводе числа 1984 программа выводит 210 (неправильный ответ).

2) при вводе числа 102 программа выводит правильный ответ 20.

3) Ошибка 1: выводить следует значение перемнной R:

строка: m := 10*d + m;

исправление: m := 10*m + d;

Ошибка 2: изменение переменной T в теле цикла

строка: if d > 1 then begin...

исправление: if d <> 1 then begin...

Обратим внимание, что тут есть две провокации-ловушки. Во-первых, обычно при разбиении числа на цифры используют условие

while n>0 do ...

но приведенный вариант равносилен:

while n>=1 do ...

Кроме того, запись

n:= (n – d) div 10;

содержит лишнее действие – вычитание младшей цифры, но это не влияет на результат, поскольку не меняет старшие цифры, а младшая все равно отбрасывается в результате целочисленного деления.

51) Сразу обратим внимание, что два блока var в программе на Паскале допустимы и не являются ошибкой.

Найдем, где программа формирует результат, то есть, что она выводит:

writeln(count);

writeln(maximum);

Это значит, что count – это счётчик значений, кратных 3, а переменная maximum должна содержать максимальное из этих чисел. При изучении программы смотрим, как изменяются эти переменные:

count := 0;

maximum := 999;

for i:=1 to n do begin

read( x );

if x mod 3 = 0 then begin

count := count + 1;

if x < maximum then

  maximum := x;

end;

end;

По поводу счётчика особых замечаний нет – начальное значение равно 0, при нахождении каждого числа, кратного 3, его значение увеличивается на 1. А вот условный оператор

if x < maximum then

maximum := x;

говорит о том, что фактически ищется минимум всех подходящих чисел. Кроме того, при начальном значении

maximum := 999;

Для того, чтобы программа правильно искала не минимум, а максимум, начальное значение должно быть меньше или равно самому меньшему из подходящих чисел (то есть, нулю):

maximum := 0;

и изменять ее, если очередное значение больше, чем ранее найденный максимум:

if x > maximum then

maximum := x;

1) При входных данных 2 9 4 3 программа выведет сначала число 2 (есть 2 значения, кратные 3), а потом – число 3 (минимальное из чисел, кратных 3).

2) При входных данных 1 2 3 4 программа выведет правильный ответ (минимальное число, кратное 3, равно максимальному).

3) Исправление ошибок:

1. Строка с ошибкой: maximum:=999;
исправление maximum:=0; (или любое отрицательное число)

2. Строка с ошибкой: if x < maximum then
исправление if x > maximum then

52) Эта задача очень похожа на задачу, которая была полностью разобрана в файле с теорией. Фактически программа вычисляет количество цифр числа, увеличенное на единицу. Приведём правильный ответ.

1)  при вводе числа 256 программа выведет число 4.

2) программа выводит правильный ответ, если сумма цифр числа на единицу больше, чем количество цифр, например, для числа 400.

3) в программе нужно исправить две ошибки:

а) неверное начальное значение переменной sum:

Было: sum := 1;

Исправление: sum := 0;

б) неверное увеличение суммы

Было: sum := sum + 1;

Исправление: sum := sum + d;

53) Эта задача очень похожа на задачу, которая была полностью разобрана в файле с теорией. Фактически программа выводит старшую цифру числа. Приведём правильный ответ.

1)  при вводе числа 256 программа выведет число 2.

2) программа выводит правильный ответ, если сумма цифр равна старшей цифре числа, например, для числа 300.

3) в программе нужно исправить две ошибки:

а) неверное начальное значение переменной sum:

Было: sum:= 1;

Исправление: sum:= 0;

б) неверное увеличение суммы

Было: sum := d;

Исправление: sum := sum + d;

54) Программа выводит значение счётчика cnt. Начальное значение счётчика – ноль, с каждым шагом цикла его значение увеличивается на x mod 2, то есть на остаток от деления числа на 2 – на последнюю цифру записи числа в двоичной системе счисления.

Выполним трассировку для числа 15:

Оператор Условие x cnt
readln(x);   15  
cnt:=0;     0
x > 0 ? да    
cnt:=cnt + x mod 2;     1
x := x div 10   1  
x > 0 ? да    
cnt:=cnt + x mod 2;     2
x := x div 10   0  
x > 0 ? нет    

1) при вводе числа 15 программа выведет число 2.

Самый сложный вопрос в этой задаче – второй (когда программа сработает верно). Как следует из трассировки, на каждом шаге отсекается одна десятичная цифра числа, поэтому это может быть только однозначное число. Для однозначного числа выполнится один шаг цикла, при этом счётчик будет увеличен на 1, если число нечётное, или останется равным 0, если число чётное. Чисел, которые содержат 0 цифр в двоичной системе нет, и есть только одно число – 1, – которое содержит одну цифру. Поэтому единственный правильный ответ:

2) программа выведет правильный ответ при вводе числа 1.

Ошибок в программе две. Во-первых, когда мы считаем цифры двоичной записи, нужно отсекать цифры не в десятичной записи числа, а в двоичной. Поэтому делить нужно не на 10, а на 2. Во-вторых, при каждом отсечении нужно увеличивать счётчик ровно на 1.

3) в программе нужно исправить две ошибки:

а) неверное учеличение счётчика cnt:

Было: cnt:=cnt + x mod 2;

Исправление: cnt:=cnt + 1;

б) неверное изменение переменной x:

Было: x:=x div 10;

Исправление: x:=x div 2;

55) Программа выводит значение счётчика cnt. Начальное значение счётчика – ноль, с каждым шагом цикла его значение увеличивается на 1.

Выполним трассировку для числа 6:

Оператор Условие x cnt
readln(x);   6  
cnt:=0;     0
x > 0 ? да    
cnt:=cnt + 1;     1
x := x mod 2;   0  
x > 0 ? нет    

1) при вводе числа 6 программа выведет число 1.

Самый сложный вопрос в этой задаче – второй (когда программа сработает верно). Как следует из трассировки, если введено чётное число, на первом же шаге значение x становится равно 0 (остатку от его деления на 2) и цикл завершается. При этом выводится значение 1. Если же вводится нечётное число, то значение x остаётся равным 1 и далее не изменяется, так что программа зацикливается.

Таким образом, программа выводит правильный ответ для чётных чисел, которые содержат одну единицу в двоичной записи, то есть, для натуральных степеней числа 2: чисел 2, 4, 8, 16 и т.д.

2) программа выведет правильный ответ при вводе числа 2.

Ошибок в программе две. Во-первых, когда мы считаем единицы двоичной записи, нужно отсекать цифры с помощью деления на 2, а не взятия остатка. Во-вторых, при каждом отсечении нужно увеличивать счётчик только тогда, когда остаток от деления (последняя цифра) равна 1.

3) в программе нужно исправить две ошибки:

а) неверное увеличение счётчика cnt:

Было: cnt:=cnt + 1;

Исправление:  if x mod 2 = 1 then cnt:=cnt + 1;

или так:

Исправление: cnt:=cnt + x mod 2;

б) неверное изменение переменной x:

Было: x:=x mod 2;

Исправление: x:=x div 2;

56) Программа выводит значение переменной k – искомого натуральнго числа. Начальное значение k – единица, с каждым шагом цикла его значение увеличивается на 1.

При вводе значения 0,4 условие s <= а неверно при входе в цикл, поэтому цикл не выполнится ни разу, и будет выведено значение k = 1:

1) при вводе числа 0,4 программа выведет число 1

Теперь выясним, когда программа выводит ответ 2. Это означает, что цикл выполнится ровно 1 раз, и переменная k увеличится с начального значения 1 до 2. Заметим, что для этого нужно, чтобы

а) выполнялось условие 1 £ A, при этом условие цикла в самом начале верно и цикл будет выполнен, по крайней мере, один раз;

б) выполнялось условие  (1/2) > A, иначе цикл не закончится после первого шага.

Очевидно, что условия a) и б) не могут выполняться одновременно ни для какого A, поэтому

2) ни для одного натурального A программа не выведет число 2

Займемся исправлением программы. Во-первых, заметим что в переменной s НЕ накапливается сумма, новое слагаемое нужно прибавлять к предыдущему значению s:

s := s + 1.0 / k;

Вторая ошибка более тонкая: в условии окончания цикла  стоит нестрогое неравенство, поэтому в условии продолжения цикла должно стоять обратное условие – строгое равенство: s < a.

3) в программе нужно исправить две ошибки:

а) неверное условие цикла:

Было: while s <= a do begin

Исправление:  while s < a do begin

б) неверное изменение переменной s:

Было: s:= 1.0/k;

Исправление: s:= s + 1.0/k;

57) Программа выводит значение переменной k – искомого натурального числа. Начальное значение k равно 0, с каждым шагом цикла его значение увеличивается на 1.

При вводе значения 1,4 условие s >= а неверно при входе в цикл, поэтому цикл не выполнится ни разу, и будет выведено значение k = 0:

1) при вводе числа 1,4 программа выведет число 0

Теперь выясним, когда программа выводит ответ 1. Это означает, что цикл выполнится ровно 1 раз, и переменная k увеличится с начального значения 0 до 1. Заметим, что для этого нужно, чтобы

а) выполнялось условие 1 ³ A, при этом условие цикла в самом начале верно и цикл будет выполнен, по крайней мере, один раз;

б) выполнялось условие (1+1) < A, иначе цикл не закончится после первого шага.

Очевидно, что условия a) и б) не могут выполняться одновременно ни для какого A, поэтому

2) ни для одного натурального A программа не выведет число 1

Займемся исправлением программы. Во-первых, заметим что начальное значение переменной s (где накапливается сумма) не равно нулю для k = 0, это первая ошибка, её нужно исправить:

s := 0;

Вторая ошибка – в условии. В заданном условии окончания цикла  стоит нестрогое неравенство, поэтому в условии продолжения цикла должно стоять обратное условие – строгое равенство: s < a.

3) в программе нужно исправить две ошибки:

а) неверное начальное значение переменной s:

Было: s:= 1;

Исправление: s:= 0;

б) неверное условие цикла:

Было: while s >= a do begin

Исправление:  while s < a do begin

Заметим, что ошибку а) можно исправить и по-другому:

а) неверное начальное значение переменной k:

Было: k:= 0;

Исправление: k:= 1;

58) Программа выводит значение переменных x и p, первое должно обозначать количество неотрицательных чисел, а второе – их произведение. Проверим, что получается при вводе последовательности -5 2 1 3.

В цикле обнаруживаем оператор ввода

read(x);

который говорит о том, что в переменной x хранится последнее введённое число (а не счётчик неотрицательных чисел!).

Это число обрабатывается условным оператором

if x >= 0 then begin

p := p*x;

count := count+1

End

Из этих строк следует, что переменная p накапливает произведение неотрицательных чисел, а переменная count – это счётчик неотрицательных чисел, который и нужно вывести на экран в конце программы.

Сначала обе переменные обнуляются, поэтому значение p так и останется равным нулю (умножив ноль на любое число, мы получим ноль). Это явная ошибка.

В то же время счётчик работает верно, и на самом деле переменная count будет содержать количество неотрицательных чисел (это можно проверить ручной прокруткой).

После окончания цикла выводится значение x – последнее введённое число, и значение p, которое всегда будет равно нулю.

Таким образом,

1) при вводе чисел -5 2 1 3 программа выведет числа 3 и 0.

Теперь отвечаем на второй вопрос – когда же программа сработает верно, несмотря на ошибки. Второе число всегда будет равно 0, поэтому в последовательности должен быть 0. В то же время последнее введённое число, которое останется в переменной x и будет выведено, должно быть равно количеству неотрицательных чисел. Эти условия выполняются, например для последовательности -5 0 1 3.

2) при вводе последовательности -5 0 1 3 программа выдает правильный ответ.

Ошибки мы уже фактически нашли ранее: во-первых, для накопления произведения переменную p не нужно обнулять, а нужно записывать в неё начальное значение 1. Во-вторых, выводить нужно не x, а count.

3) в программе нужно исправить две ошибки:

а) неверное начальное значение переменной p:

Было: p:= 0;

Исправление: p:= 1;

б) неверный оператор вывода:

Было: writeln(x);

Исправление:  writeln(count);

59) Программа выводит значение переменных s и mx, первое должно обозначать сумму отрицательных чисел, а второе – максимальное число в последовательности. Проверим, что получается при вводе последовательности -5 2 -4 3.

В цикле обнаруживаем оператор ввода

read(x);

который говорит о том, что в переменной x хранится последнее введённое число (а не счётчик неотрицательных чисел!).

Это число обрабатывается условными операторами

if x < 0 then

s := x;

if x > mx then

mx := x;

Из этих строк следует, что в переменную s записывается последнее отрицательное число, а переменная mx – это максимальное из всех элементов последовательности. Сначала обе переменные обнуляются.

Таким образом,

1) при вводе чисел -5 2 -4 3 программа выведет числа -4 и 3.

Программа неверно подсчитала сумму отрицательных чисел, вместо неё выведено последнее отрицательное число. Поэтому первое значение будет правильным, если это отрицательное число всего одно.

Обратим внимание, что начальное значение переменной mx равно 0, поэтому если все числа меньше нуля, максимум будет вычислен неверно. Для правильной программы это начальное значение должно быть не больше, чем минимальное допустимое число, то есть -1000.

Таким образом, программа сработает верно, если в последовательности только одно отрицательное число. Это условия выполняются, например для последовательности -5 0 1 3.

2) при вводе последовательности -5 0 1 3 программа выдает правильный ответ.

Одну ошибку мы уже нашли ранее: начальное значение для переменной mx должно быть не более -1000. Вторая ошибка – сумма отрицательных чисел не накапливается.

3) в программе нужно исправить две ошибки:

а) неверное начальное значение переменной mx:

Было: mx:= 0;

Исправление: mx:= -1000;

б) неверный оператор накопления суммы:

Было: s:=x;

Исправление:  s:=s+x;

60) Проверим, что получается при вводе числа N = 134.

Сначала в переменную maxDigit записывается начальное значение N mod 10,  это последняя цифра в десятичной записи числа, она равна 4. Заметим, что проверки на делимость этой цифры на 3 не было!

Затем в цикле перебираются все цифры числа в обратном порядке (4, 3 и 1), если очередная цифра делится на 3 и больше, чем существующее значение maxDigit, значение maxDigit обновляется – мы нашли новый максимум. в данном случае цифр больше, чем 4, в числе нет, поэтому после окончания цикла maxDigit=4, это число и выводится на экран.

1) При вводе числа 134 программы выводит число 4.

Программа будет выводить правильный ответ, если последняя цифра делится на 3 (например, для числа 136). Есть и другой вариант – когда последняя цифра меньше, чем наибольшая цифра, которая делится на 3 (например, для числа 631).

2) Программа выведет правильный ответ при вводе числа 136.

Для того, чтобы исправить программу, нужно изменить начальное значение maxDigit. Проще всего взять значение, заведомо меньшее, чем любая цифра, например, -1.

Поскольку ноль делится на любое число, проверка условия maxDigit=0 не поможет определить, есть ли в числе цифра, кратная трём. Это условие нужно заменить на maxDigit=-1.

3) В программе нужно исправить две ошибки:

а) Было: maxDigit := N mod 10;

Исправление: maxDigit := -1;

б) Было: if maxDigit=0 then

Исправление: if maxDigit=-1 then

61) Задача аналогична задача 57, поэтому приведем только решение с небольшими комментариями.

1) при вводе числа 1.8 программа выведет число 1 (проверяется ручной прокруткой).

В программе сделано несколько ошибок, и в некоторых случаях они могут скомпенсировать друг друга. Во-первых, цикл заканчивается, когда s³a, то есть мы всегда находим k, которое на единицу больше правильного значения. С другой стороны, перед циклом стоит два присваивания:

k:= 0;

s:= 1;

Это значит, что значение k=1 мы уже включили в сумму, но значение переменной k ещё не обновили. Проследим, как будет фактически изменяться значение переменной s из-за этой ошибки:

s =     1 ® 1+1=2  ® 2+1/2=2,5 ® 2,5+1/3=2,833

k=0   k=1 k=2     k=3           

А вот как нужно было (результат k=0 означает, что ни одного натурального k, удовлетворяющего условию задачи, не существует):

s = 1 ® 1+1/2=1,5 ® 1,5+1/3=1,833 ® 1,833+1/4=2,083

k=0 k=1    k=2         k=3           

Представим эти данные на диаграмме:

Из этой схемы видно, что при конечном значении s не более 1,5 программа выдаёт правильный ответ!

2) При вводе числа 1.2 программа выводит правильный ответ.

3) В программе две ошибки:

а)

или так: Было: s:=1; Исправление: s:=0;  
Неверное присваивание:

Было: k:=0;

Исправление: k:=1;

б) Неверный вывод результата:

Было: write(k);

Исправление:  write(k-1);

62) Задача аналогична задача 61, поэтому приведем только решение с небольшими комментариями.

1) при вводе числа 1.2 программа выведет число 2 (проверяется ручной прокруткой).

В программе сделано несколько ошибок, и в некоторых случаях они могут скомпенсировать друг друга. Во-первых, цикл заканчивается, когда s³a, кроме того, после суммирования в цикле значение k ещё увеличивается! Поэтому мы всегда находим k, которое на 2 больше правильного значения. С другой стороны, перед циклом стоит два присваивания:

k:= 1;

s:= 1;

В теле цикла это же значение k на первом шаге будет добавлено к сумме, то есть, единицу мы добавляем два раза! Проследим, как будет фактически изменяться значение переменной s из-за этой ошибки:

s =     1 ® 1+1=2  ® 2+1/2=2,5 ® 2,5+1/3=2,833

k=1   k=2 k=3     k=4           

А вот как нужно было:

s = 1 ® 1+1/2=1,5 ® 1,5+1/3=1,833 ® 1,833+1/4=2,083

k=0 k=1    k=2         k=3           

Представим эти данные на диаграмме:

Из этой схемы видно, что при конечном значении s в интервалах 1,5 < s < 1,83 и 2 < s < 2,083 программа выдаёт правильный ответ!

2) При вводе числа 1,6 программа выводит правильный ответ.

3) В программе две ошибки:

а) Неверное присваивание:

Было: s:=1;

Исправление: s:=0;

б) Неверный вывод результата:

Было: write(k);

Исправление:  write(k-2);

63) Сначала рассмотрим, как работает вся программа целиком. Цикл, в котором изменяется переменная N – это классический алгоритм перебора всех цифр числа, начиная с последней. Последняя цифра с помощью операции mod записывается в переменную digit, после каждого шага цикла N делится на 10 нацело, то есть, последняя цифра отсекается. Цикл продолжается, пока в числе остаются необработанные цифры:

while N > 0 do begin

digit := N mod 10;

...

N := N div 10;

end;

Вместо многоточия в программе стоит оператор

if digit < 7 then

sum := sum + 1;

Это значит, что если очередная цифра оказалась меньше 7, сумма увеличивается на единицу (!). Так как в начале сумма равна 0, после окончания цифра в переменной sum будет количество цифр, меньших 7 (а не их сумма, как нам нужно по условию!).

Обратим внимание на оператор вывода:

writeln(digit);

Он выводит последнее значение цифры, которое оказалось в переменной digit (а не сумму цифр, меньших 7, как требуется по условию!). Поскольку цифры перебираются с конца числа, это будет самая первая цифра этого числа.

Таким образом, уже готовы все ответы:

1) при вводе числа 456 программа выведет 4 (первую цифру числа).

2) программа выведет верное значение, если первая цифра числа равна сумме цифр, меньших 7, например, для числа 743 первая цифра (7) равна сумме цифр, меньших 7 (4 + 3).

3) в программе нужно исправить две ошибки

a. Неверное изменение переменной sum:

Было: sum:=sum+1;

Исправление: sum:=sum+digit;

b. Неверный вывод результата:

Было: writeln(digit);

Исправление:  writeln(sum);

 


[1] Аналогичная ситуация возникает при решении уравнения методом деления отрезка пополам (кто помнит :-).

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


Дата добавления: 2018-06-01; просмотров: 402; Мы поможем в написании вашей работы!

Поделиться с друзьями:






Мы поможем в написании ваших работ!