close

Вход

Забыли?

вход по аккаунту

+y - Гимназия №116

код для вставкиСкачать
-1-
Г ОСУДАРСТВЕННОЕ БЮДЖЕТНОЕ ОБЩЕОБРАЗОВАТЕЛЬНОЕ УЧРЕЖДЕНИЕ
ГИМНАЗИЯ № 116
П РИМОРСКОГО РАЙОНА С АНКТ -П ЕТЕРБУРГА
C1
Поиск ошибок в программе
со сложным условием
3 балла
-2-
С1 2009-2011
Пример решения задачи:
Требовалось написать программу, которая вводит с клавиатуры координаты точки на
плоскости (x, y – действительные числа) и определяет принадлежность точки заштрихованной области, включая ее границы. Программист написал программу неправильно.
var x,y: real;
begin
readln(x,y);
if y <= 1 then
if x >= 0 then
if y >= sin(x) then
write('принадлежит')
else write('не принадлежит')
end.
Последовательно выполните следующее:
1) Приведите пример таких чисел x, y, при которых программа неверно решает поставленную задачу. 2) Укажите, как нужно доработать программу, чтобы не было
случаев ее неправильной работы. (Это можно сделать несколькими способами, поэтому можно указать любой способ доработки исходной программы).
РЕШЕНИЕ
1. Сначала необходимо найти правильные условия, которым отвечают точки выделенной области. При этом можно ориентироваться на условия, указанные в исходной программе – они неверны только частично.
Выделенная область ограничена (с учетом границы получаем нестрогие неравенства):
- по координате y: y <= 1 и y >= sin(x)
- по координате x: x >= 0, но при этом x ограничен в точке максимума функции y =
sin(x) – то есть x <= pi/2 – именно это условие и забыто в исходной программе.
2. Найти области координатной плоскости, по которым программа ошибочно выдает
сообщение «принадлежит» из-за потери четвертного
условия. На рисунке это заштрихованные области: все y  1 y
они удовлетворяют трем условиям исходной программы, но лежат правее x = pi/2.
3. Выбрать любую надежную (лучше не на границах)
x
точку из найденной заштрихованной области, например x = , y = 0,5 – это ответ на 1-ый вопрос.
y  sin x
4. Исправляем программу, при этом желательно от
многоэтажных if then else перейти к составному условию через and или or:
var x,y: real;
begin
readln(x,y);
if (x >= 0) and (x <= pi/2) and (y <= 1) and (y >= sin(x))
then write('принадлежит') else write('не принадлежит');
end.
-3-
РЕКОМЕНДАЦИИ
1. Пояснения к ответам не требуются.
2. Эффективность работы программы (рациональность решения) не учитывается.
3. В ответе можно указать только исправления программы, но лучше привести ее полностью.
4. Синтаксические ошибки, не искажающие логику программы, не учитываются. Например, если забыли «;» в конце оператора – оценка снижаться не будет; но указание
x=6.5 при объявленной в программе переменной x:integer может считаться ошибкой.
Конечно, желательно синтаксических ошибок вообще не допускать.
5. На примере вышеприведенной программы. Конструкция else write ('не принадлежит')
во многих программах относится только к последнему if then – поэтому при невыполнении двух других условий: y > 1 (первое условие ложно) или x < 0 (второе условие
ложно) программа вообще не выдаст никакого сообщения, то есть, также работает неправильно. Таким образом, координаты любой точки, для которой y > 1 или x < 0, могут быть указаны в ответе как пример набора входных данных, при которых программа
работает неправильно.
Возможная доработка программы с помощью полного оператора условия:
if x <= pi/2 then
if y <= 1 then
if x >= 0 then
if y >= sin(x) then write('принадлежит') else write('не принадлежит')
else write('не принадлежит')
else write('не принадлежит')
else write('не принадлежит');
6. Многоэтажные полные операторы условия if then else для непрофессионала (для вас)
тяжеловесны и малопонятны. Поэтому рациональнее, насколько это возможно, избавиться от else, ограничившись кратким форматом условия if then – это можно осуществить с помощью составных условий, используя конструкции and или or.
ЗА ЧТО СТАВЯТСЯ БАЛЛЫ
1. Только за указание координат точки (ответ на вопрос 1) дается 1 балл из 3-х возможных. Учитывая широкий спектр правильных ответов, можно с большой вероятностью
ее просто угадать.
2. Если исправленная программа хоть немного увеличивает множество правильных
решений относительно исходной программы, - это еще + 1 балл (даже, если программа
не до конца верна).
ЗАДАЧИ
ОБЩЕЕ УСЛОВИЕ ДЛЯ СЛЕДУЮЩИХ ЗАДАЧ
Требовалось написать программу, которая вводит с клавиатуры координаты точки на плоскости (x, y – действительные числа) и определяет принадлежность точки заштрихованной области, включая ее границы. Программист торопился и написал программу неправильно. Последовательно выполните следующее:
1) Приведите пример таких чисел x, y, при которых данная программа неверно решает задачу.
2) Укажите, как нужно доработать программу, чтобы не было случаев ее неправильной работы.
-4-
1. var x,y: real;
begin
readln(x,y);
if x*x+y*y >= 4 then
if x <= 2 then
if y <= x then
write('принадлежит')
else
write('не принадлежит')
end.
x x 2
y  sin x
2. var x,y: real;
begin
readln(x,y);
if y >= -1 then
if y <= sin(x) then
if y >= x-1 then
write('принадлежит')
else
write('не принадлежит')
end.
3. var x, y: real;
begin
readln(x, y);
if x*x + y*y >= 4 then
if x >= –2 then
if y <= –x then
write('принадлежит')
else
write('не принадлежит')
end.
4. var x, y: real;
begin
readln(x, y);
if y <= sin(x) then
if y <= 0.5 then
if y >= 0 then
write('принадлежит')
else
write('не принадлежит');
end.
yx
x2  y 2  4
y  1
y  x 1
y  x
x 2  y 2  22
x  2
y  sin(x)
y  0,5
-5-
5. var x, y: real;
begin
readln(x, y);
if y <= x then
if y >= -x then
if x*x+y*y <= 1 then
write('принадлежит')
else
write('не принадлежит');
end.
6. var x, y: real;
begin
readln(x, y);
if y >= x then
if x <= 0 then
if x*x+y*y <= 1 then
write('принадлежит')
else write('не принадлежит');
end.
7. var x, y: real;
begin
readln(x, y);
if y <= x then
if y <= -x then
if y >= x*x-2 then
write('принадлежит')
else write('не принадлежит');
end.
8. var x, y: real;
begin
readln(x, y);
if y >= x then
if y >= 0 then
if y <= 2-x*x then
write('принадлежит')
else
write('не принадлежит');
end.
y
yx
x2  y 2  1
x
y  x
y
x2  y 2  1
yx
x
y
y  x2  2
x
yx
y  x
y
y  2 x
yx
2
x
-6-
C1 2012-2013
Задание 1.
Требовалось написать программу, при выполнении которой с
клавиатуры считываются координаты точки на плоскости (x, y –
действительные числа) и определяется принадлежность этой точки
заданной закрашенной области (включая границы). Программист
торопился и написал программу неправильно.
var x,y: real;
begin
readln(x,y);
if y<=2-x then
if y>=0 then
if y>=x*x then
write('принадлежит')
else
write('не принадлежит')
end.
Последовательно выполните следующее.
1. Перерисуйте и заполните таблицу, которая показывает, как работает программа при
аргументах, принадлежащих различным областям (A,B, C, D, E, F,G и H). Точки, лежащие на границах областей, отдельно не рассматривать.
Область
y<=2-x?
y>=0?
y>=x*x?
вывод
верно?
A
B
C
D
E
F
G
H
В столбцах условий укажите "да", если условие выполнится, "нет" если условие не выполнится, "—" (прочерк), если условие не будет проверяться, «не изв.», если программа ведет себя по-разному для разных значений, принадлежащих данной области. В
столбце "Программа выведет" укажите, что программа выведет на экран. Если программа ничего не выводит, напишите "—" (прочерк). Если для разных значений, принадлежащих области, будут выведены разные тексты, напишите «не изв». В последнем
столбце укажите "да" или "нет".
2. Укажите, как нужно доработать программу, чтобы не было случаев ее неправильной
работы. (Это можно сделать несколькими способами, достаточно указать любой способ
доработки исходной программы.)
-7-
Решение
1. Второе условие проверяется в программе только тогда, когда истинно первое, а третье – только тогда, когда истинны первые два. В остальных ячейках (если
условие не проверяется) нужно ставить прочерк:
Обл. 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
нет
–
–
–
нет
-8-
2. Простейший способ исправить ошибку – построить условия для каждой из закрашенных областей, и затем объединить их с помощью операции ИЛИ. Записываем условия для обеих интересующих нас областей (С и 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('не принадлежит');
-9-
Задание 2.
var x,y: real;
begin
readln(x,y);
if y>=0 then
if y>=2-x then
if y<=x*x then
write('принадлежит')
else
write('не принадлежит')
end.
Область
y>=0?
y>=2-x?
A
B
C
D
E
F
G
H
Задание 3.
var x, y: real;
begin
readln(x, y);
if x <= 1 then
if y <= 1 then
if x*x + y*y <= 1 then
write('принадлежит')
else
write('не принадлежит');
end.
Область
x <= 1
y <= 1
A
B
C
D
E
F
вывод
y<=x*x?
y
y=1 С
верно?
С
D
E
B
B
А
А
x2+y2=1
x*x + y*y <= 1
А
F
x
А
x=1
B
F
вывод
верно?
- 10 -
Задание 4.
var x, y: real;
begin
readln(x, y);
if y >= 0 then
if x <= 1 then
if y >= x*x then
write('принадлежит')
else
write('не принадлежит');
end.
Область
y >= 0
x <= 1
A
B
C
D
E
F
Задание 5.
var x, y: real;
begin
readln(x, y);
if x <= 1 then
if y >= 1-x then
if y >= x*x then
write('принадлежит')
else
write('не принадлежит');
end.
Область
x <= 1
y >= 1-x
A
B
C
D
E
F
G
H
y
C
A
A
D
y=x2
B
E x=1
F
F
F
вывод
y >= x*x
A
y
y=1-x
E
B
C
F
y >= x*x
верно?
H y=x2
B
F
x
C D x=1
F
G
вывод
Е x
верно?
- 11 -
Задание 6.
var x, y: real;
begin
G y
J
H
readln(x, y);
B y=x-1
if x >= 0 then
D
C A
E
if y <= 1 then
x
if (x*x + y*y <= 1) and (y >= x-1) then
C A
D
x
E
F
write('принадлежит')
x2+y2=1
else
write('не принадлежит');
K
end.
x*x + y*y <= 1
Область
x >= 0
y <= 1
вывод
верно?
and (y >= x-1)
A
B
C
D
E
F
G
H
J
K
MINTSIS
@ MAIL.RU
1/--страниц
Пожаловаться на содержимое документа