Решение задач С-1

advertisement
Задачи
на пересечение областей (C1):
«на стыке алгебры и логики»
Д.Ю. Усенков,
О.Б. Богомолова
Задача С1 (2011 г.)
Требовалось написать программу, при выполнении которой с
клавиатуры считываются координаты точки на плоскости (x,y –
действительные числа) и определяется принадлежность этой точки
заданной заштрихованной области (включая границы).
Программист торопился и написал программу неправильно.
ПРОГРАММА НА ПАСКАЛЕ
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.
ПРОГРАММА НА БЕЙСИКЕ
INPUT x, y
IF y<=x THEN
IF y<=-x THEN
IF y>=x*x-2 THEN
PRINT "принадлежит"
ELSE
PRINT "не принадлежит"
ENDIF
ENDIF
ENDIF
END
ПРОГРАММА НА СИ
void main(void)
{ float x,y;
scanf("%f%f",&x,&y);
if (y<=x)
if (y<=-x)
if (y>=x*x-2)
printf("принадлежит");
else
printf("не принадлежит");
}
Последовательно выполните следующее:
1) Приведите пример таких чисел x, y, при которых программа неправильно решает
поставленную задачу.
2) Укажите, как нужно доработать программу, чтобы не было случаев ее неправильной
работы. (Это можно сделать несколькими способами, поэтому можно указать любой
правильный способ доработки исходной программы).
Решение:
всё, что ниже графика –
условие «y  f(x)»
y
всё, что выше графика –
условие «y  f(x)»
y = f(x)
всё, что левее графика –
условие «x  f -1(y)»
всё, что правее графика –
условие «x  f -1(y)»
x
y = f(x)
Решение:
y
y = x2 - 2
0
xx


y = -x
y=x y=x
( y  x2 – 2
AND y  -x
)
OR
y = -x
(y  x2 – 2
AND y  x
)
Решение:
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.
1. В цепочке последовательных
операторов if ветвь else всегда
относится к последнему if.
2. Цепочка последовательных
if ... then эквивалентна записи
одного if с условиями, записанными
через AND.
if (y<=x) AND (y<=-x) AND
write('принадлежит')
else write('не принадлежит')
(y>=x*x-2) then
Но это условие – неверное! Будем искать правильное
Решение:
if (y<=x) AND (y<=-x) AND
write('принадлежит')
else write('не принадлежит')
(y>=x*x-2) then
y
условие «y  f(x)» –
всё, что ниже графика
условие «y  f(x)» –
всё, что выше графика
условие «x  f-1(y)» –
всё, что левее графика
условие «x  f-1(y)» –
всё, что правее графика
AND – пересечение областей,
OR – объединение областей
y = x2 - 2
0
x
1
2
y=x
y = -x
Области 1 и 2 –
точки, которые
программа
обрабатывает
ошибочно
Решение:
Области 1 и 2 – точки, которые программа
обрабатывает ошибочно
y
2
1
(-2, 2)
y = x2 - 2
(2, 2)
Пример точки,
обрабатываемой
ошибочно
0
x
(- 2 , 0)
(-1, -1)
( 2 , 0)
y=x
(0, -2)
y = -x
(1, -1)
Решение:
Ошибочная программа
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.
Правильная программа
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.
if (y>=x*x-2 AND y<=-x)
OR (y>=x*x-2 AND y<=x) then
(y  x2 – 2 AND y  -x) OR
(y  x2 – 2 AND y  x)
Задача С1 (2009 г.)
Требовалось написать программу, при выполнении которой с
клавиатуры считываются координаты точки на плоскости (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.
ПРОГРАММА НА БЕЙСИКЕ
INPUT x, y
IF y<=1 THEN
IF x>=0 THEN
IF y>=SIN(x) THEN
PRINT "принадлежит"
ELSE
PRINT "не принадлежит"
ENDIF
ENDIF
ENDIF
END
ПРОГРАММА НА СИ
void main(void)
{ float x,y;
scanf("%f%f",&x,&y);
if (y<=1)
if (x>=0)
if (y>=sin(x))
printf("принадлежит");
else
printf("не принадлежит");
}
Последовательно выполните следующее:
1) Приведите пример таких чисел x, y, при которых программа неправильно решает
поставленную задачу.
2) Укажите, как нужно доработать программу, чтобы не было случаев ее неправильной
работы. (Это можно сделать несколькими способами, поэтому можно указать любой
правильный способ доработки исходной программы).
Задача С1 (2010 г.)
Требовалось написать программу, при выполнении которой с
клавиатуры считываются координаты точки на плоскости (x,y –
действительные числа) и определяется принадлежность этой точки
заданной заштрихованной области (включая границы).
Программист торопился и написал программу неправильно.
ПРОГРАММА НА ПАСКАЛЕ
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.
ПРОГРАММА НА БЕЙСИКЕ
INPUT x, y
IF x*x+y*y>=4 THEN
IF x>= –2 THEN
IF y<= –x THEN
PRINT "принадлежит"
ELSE
PRINT "не принадлежит"
ENDIF
ENDIF
ENDIF
END
ПРОГРАММА НА СИ
void main(void)
{ float x,y;
scanf("% f % f",&x,&y);
if (x*x+y*y>=4)
if (x>= –2)
if (y<= –x)
printf("принадлежит");
else
printf("не принадлежит");
}
Последовательно выполните следующее:
1) Приведите пример таких чисел x, y, при которых программа неправильно решает
поставленную задачу.
2) Укажите, как нужно доработать программу, чтобы не было случаев ее неправильной
работы. (Это можно сделать несколькими способами, поэтому можно указать любой
правильный способ доработки исходной программы).
Download