24 задание ЕГЭ часть 2
«Исправление ошибок в программе»
Предисловие
Вторая и заключительная статья по теме. Здесь будут представлены задания с 2009 по 2015 годы. Перейдем к рассмотрению задач!
Демонстрационный вариант ЕГЭ 2015 г. ИНФОРМАТИКА и ИКТ, 11 класс
1. На обработку поступает последовательность из четырёх неотрицательных целых чисел (некоторые числа могут быть одинаковыми). Нужно написать программу, которая выводит на экран количество нечётных чисел в исходной последовательности и максимальное нечётное число. Если нечётных чисел нет, требуется на экран вывести «NO». Известно, что вводимые числа не превышают 1000. Программист написал программу неправильно. Ниже эта программа для Вашего удобства приведена на пяти языках программирования.
Бейсик |
Python |
CONST n = 4 count = 0 maximum = 999 FOR I = 1 TO n INPUT x IF x mod 2 <> 0 THEN count = count + 1 IF x > maximum THEN maximum = I END IF END IF NEXT I IF count > 0 THEN PRINT count PRINT maximum ELSE PRINT "NO" END IF |
n = 4 count = 0 maximum = 999 for i in range(1, n + 1): x = int(input()) if x % 2 != 0: count += 1 if x > maximum: maximum = i if count > 0: print(count) print(maximum) else: print("NO") |
Алгоритмический язык |
Паскаль |
алг нач цел n = 4 цел i, x цел maximum, count count := 0 maximum := 999 нц для i от 1 до n ввод x если mod(x, 2) <> 0 то count := count + 1 если x > maximum то maximum := i все все кц если count > 0 то вывод count, нс вывод maximum иначе вывод "NO" все кон |
const n = 4; var i, x: integer; var maximum, count: integer; begin count := 0; maximum := 999; for i := 1 to n do begin read(x); if x mod 2 <> 0 then begin count := count + 1; if x > maximum then maximum := i end end; if count > 0 then begin writeln(count); writeln(maximum) end else writeln('NO') end. |
С++ |
|
#include <stdio.h> int main(void) { const int n = 4; int i, x, maximum, count; count = 0; maximum = 999; for (i = 1; i <= n; i++) { scanf("%d",&x); if (x % 2 != 0) { count++; if (x > maximum) maximum = i; } } if (count > 0) { printf("%d\n", count); printf("%d\n", maximum); } else printf("NO\n"); } |
Последовательно выполните следующее.
1. Напишите, что выведет эта программа при вводе последовательности:
2 9 4 3
2. Приведите пример такой последовательности, содержащей хотя бы одно нечётное число, что, несмотря на ошибки, программа печатает правильный ответ.
3. Найдите все ошибки в этой программе (их может быть одна или несколько). Известно, что каждая ошибка затрагивает только одну строку и может быть исправлена без изменения других строк. Для каждой ошибки:
1) выпишите строку, в которой сделана ошибка;
2) укажите, как исправить ошибку, т.е приведите правильный вариант строки.
Достаточно указать ошибки и способ их исправления для одного языка программирования.
Обратите внимание, что требуется найти ошибки в имеющейся программе, а не написать свою, возможно, использующую другой алгоритм решения. Исправление ошибки должно затрагивать только строку, в которой находится ошибка.
1. Разберемся, как выполняется данный алгоритм для данной последовательности:
Шаг 1 |
count = 0 |
maximum = 999 |
X = 2 |
Шаг 2 |
count = 0 |
maximum = 999 |
X = 9 |
Шаг 3 |
count = 1 |
maximum = 999 |
X = 4 |
Шаг 4 |
count = 1 |
maximum = 999 |
X = 3 |
Шаг 5 |
count = 2 |
maximum = 999 |
Печать «2» |
Шаг 6 |
Печать «999» |
|
|
2. Например, 2 4 6 9. Убедимся:
Шаг 1 |
count = 0 |
maximum = 999 |
X = 2 |
Шаг 2 |
count = 0 |
maximum = 999 |
X = 4 |
Шаг 3 |
count = 0 |
maximum = 999 |
X = 6 |
Шаг 4 |
count = 0 |
maximum = 999 |
X = 999 |
Шаг 5 |
count = 1 |
maximum = 999 |
Печать «1» |
Шаг 6 |
Печать «999» |
|
|
3. Первая ошибка допущена в шестой строке «maximum := 999;» Очевидно, что т. к. числа ввода неотрицательные, необходимо, чтобы максимум был меньше наименьшего неотрицательного (т. е., 0). Поэтому корректная строка:
maximum := -1;
И следовательно, вторая ошибка допущена в четырнадцатой строке: «maximum := i». В ответе нужен не индекс этого числа, а само число. Т.е. должно быть «maximum := x».
Демонстрационный вариант ЕГЭ 2014 г. ИНФОРМАТИКА и ИКТ, 11 класс
2. Требовалось написать программу, при выполнении которой с клавиатуры считывается натуральное число N, не превосходящее 109, и выводится максимальная цифра этого числа. Программист торопился и написал программу неправильно. (Ниже для Вашего удобства программа представлена на четырёх языках программирования.)
Бейсик |
Алгоритмический язык |
DIM N AS LONG INPUT N max_digit = 9 WHILE N >= 10 digit = N MOD 10 IF digit > max_digit THEN max_digit = digit END IF N = N \ 10 WEND PRINT max_digit END |
алг нач цел N, digit, max_digit ввод N max_digit := 9 нц пока N >= 10 digit := mod(N, 10) если digit > max_digit то max_digit := digit все N := div(N, 10) кц вывод max_digit кон |
С++ |
Паскаль |
#include<stdio.h> int main() { long int N; int digit, max_digit; scanf("%ld", &N); max_digit = 9; while (N >= 10) { digit = N % 10; if (digit > max_digit) max_digit = digit; N = N /10; } printf("%d", max_digit); } |
var N: longint; digit, max_digit: integer; begin readln(N); max_digit := 9; while N >= 10 do begin digit := N mod 10; if digit > max_digit then max_digit := digit; N := N div 10; end; writeln(max_digit); end. |
Последовательно выполните следующее.
1. Напишите, что выведет эта программа при вводе числа 423.
2. Найдите все ошибки в этой программе (их может быть одна или несколько). Для каждой ошибки:
1) выпишите строку, в которой сделана ошибка;
2) укажите, как исправить ошибку, – приведите правильный вариант строки.
Обратите внимание, что требуется найти ошибки в имеющейся программе, а не написать свою, возможно, использующую другой алгоритм решения. Исправление ошибки должно затрагивать только строку, в которой находится ошибка.
1. Разберемся, как выполняется данный алгоритм для числа 423:
Шаг 1 |
N = 423 |
Digit = 3 |
N= 42 |
Шаг 2 |
N = 42 |
Digit = 2 |
N = 4 |
Шаг 3 |
Печать «9» |
|
|
2. Первая ошибка допущена в пятой строке «max_digit := 9;» Очевидно, что минимальная цифра – 0. Поэтому правильная строка выглядит следующим образом: «max_digit := 0;»
Вторая ошибка допущена в шестой строке: «while N >= 10 do». Цикл должен закончиться, когда N будет равным 0. Т.е. он выполняется, пока N > 0:
«while N > 0 do».
Демонстрационный вариант ЕГЭ 2013 г. ИНФОРМАТИКА и ИКТ, 11 класс
3.
Требовалось написать программу, при выполнении которой с клавиатуры считывается координата точки на прямой (x – действительное число) и определяется принадлежность этой точки одному из выделенных отрезков В и D (включая границы). Программист торопился и написал программу неправильно.
Бейсик |
Алгоритмический язык |
INPUT x IF x>=-3 THEN IF x<=9 THEN IF x>1 THEN PRINT "не принадлежит" ELSE PRINT "принадлежит" ENDIF ENDIF ENDIF END |
алг нач вещ x ввод x если x>=-3 то если x<=9 то если x>1 то вывод 'не принадлежит' иначе вывод 'принадлежит' все все все кон |
С++ |
Паскаль |
void main(void) { float x; scanf("%f",&x); if(x>=-3) if(x<=9) if(x>1) printf("не принадлежит"); else printf("принадлежит"); } |
var x: real; begin readln(x); if x>=-3 then if x<=9 then if x>1 then write('не принадлежит') else write('принадлежит') end. |
Последовательно выполните следующее.
1. Перерисуйте и заполните таблицу, которая показывает, как работает программа при аргументах, принадлежащих различным областям (A, B, C, D и E). Границы (точки –3, 1, 5 и 9) принадлежат заштрихованным областям (B и D соответственно).
Область |
Условие 1 (x >= –3) |
Условие 2 (x <= 9) |
Условие 3 (x > 1) |
Программа выведет |
Область обрабатывается верно |
A |
|
|
|
|
|
B |
|
|
|
|
|
C |
|
|
|
|
|
D |
|
|
|
|
|
E |
|
|
|
|
|
В столбцах условий укажите «Да», если условие выполнится; «Нет», если условие не выполнится; «—» (прочерк), если условие не будет проверяться; «не изв.», если программа ведет себя по-разному для разных значений, принадлежащих данной области. В столбце «Программа выведет» укажите, что программа выведет на экран. Если программа ничего не выводит, напишите «—» (прочерк). Если для разных значений, принадлежащих области, будут выведены разные тексты, напишите «не изв.». В последнем столбце укажите «Да» или «Нет».
2. Укажите, как нужно доработать программу, чтобы не было случаев её
неправильной работы. (Это можно сделать несколькими способами, достаточно указать любой способ доработки исходной программы.)
1. Заполним таблицу:
Область |
Условие 1 (x >= –3) |
Условие 2 (x <= 9) |
Условие 3 (x > 1) |
Программа выведет |
Область обрабатывается верно |
A |
нет |
- |
- |
- |
нет |
B |
да |
да |
нет |
принадлежит |
да |
C |
да |
да |
да |
Не принадлежит |
да |
D |
да |
да |
да |
Не принадлежит |
нет |
E |
да |
нет |
- |
- |
нет |
2. Будем проверять принадлежность двум отрезкам (для определения границ воспользуемся оператором «и»), используя оператор «или»:
var x: real;
begin
readln(x);
if ((x >= -3) and (x <= 1)) or ((x >= 5) and (x <= 9)) then
writeln('Принадлежит')
else
writeln('Не принадлежит');
end.
Демонстрационный вариант ЕГЭ 2012 г. ИНФОРМАТИКА и ИКТ, 11 класс
4.
Требовалось написать программу, при выполнении которой с клавиатуры считываются координаты точки на плоскости (x, y – действительные числа) и определяется принадлежность этой точки заданной закрашенной области (включая границы). Программист торопился и написал программу неправильно.
Бейсик |
Алгоритмический язык |
INPUT x, y IF y>=x THEN IF y>=0 THEN IF y<=2-x*x THEN PRINT "принадлежит" ELSE PRINT "не принадлежит" ENDIF ENDIF ENDIF END |
алг нач вещ x,y ввод x,y если y>=x то если y>=0 то если y<=2-x*x то вывод 'принадлежит' иначе вывод 'не принадлежит' все все все кон |
С++ |
Паскаль |
void main(void){ float x,y; scanf("% f % f",&x,&y); if (y>=x) if (y>=0) if (y<=2-x*x) printf("принадлежит"); else printf("не принадлежит"); } |
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. |
Последовательно выполните следующее.
1. Перерисуйте и заполните таблицу, которая показывает, как работает программа при аргументах, принадлежащих различным областям (A, B, C, D, E, F, G и H). Точки, лежащие на границах областей, отдельно не рассматривать.
Область |
Условие 1 (y>=x) |
Условие 2 (y>=0) |
Условие 3 (y<=2–x*x) |
Программа выведет |
Область обрабатывается верно |
A |
|
|
|
|
|
B |
|
|
|
|
|
C |
|
|
|
|
|
D |
|
|
|
|
|
E |
|
|
|
|
|
F |
|
|
|
|
|
G |
|
|
|
|
|
H |
|
|
|
|
|
В столбцах условий укажите "да", если условие выполнится, "нет" если условие не выполнится, "—" (прочерк), если условие не будет проверяться, «не изв.», если программа ведет себя по-разному для разных значений, принадлежащих данной области. В столбце "Программа выведет" укажите, что программа выведет на экран. Если программа ничего не выводит, напишите "—" (прочерк). Если для разных значений, принадлежащих области, будут выведены разные тексты, напишите «не изв». В последнем столбце укажите "да" или "нет".
2. Укажите, как нужно доработать программу, чтобы не было случаев ее неправильной работы. (Это можно сделать несколькими способами, достаточно указать любой способ доработки исходной программы.)
1. Заполним таблицу:
Область |
Условие 1 (y>=x) |
Условие 2 (y>=0) |
Условие 3 (y<=2–x*x) |
Программа выведет |
Область обрабатывается верно |
A |
да |
да |
нет |
Не принадлежит |
да |
B |
да |
нет |
- |
- |
нет |
C |
нет |
- |
- |
- |
нет |
D |
нет |
- |
- |
- |
нет |
E |
да |
да |
да |
принадлежит |
да |
F |
да |
нет |
- |
- |
нет |
G |
нет |
- |
- |
- |
нет |
H |
нет |
- |
- |
- |
нет |
2. Разобьем решение на 2 части для x: от -2 до 0 и от 0 до 1:
var x,y: real;
begin
readln(x,y);
if ((x >= -2) and (x <= 0) and (y >= x) and (y <= 2-sqr(x))) or (x >= 0) and (x <= 1) and (y >= 0) and (y <= 2-sqr(x)) then
writeln('Принадлежит')
else
writeln('Не принадлежит');
end.
Демонстрационный вариант ЕГЭ 2011 г. ИНФОРМАТИКА и ИКТ, 11 класс
5.
Требовалось написать программу, при выполнении которой с клавиатуры считываются координаты точки на плоскости (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) Укажите, как нужно доработать программу, чтобы не было случаев ее неправильной работы. (Это можно сделать несколькими способами, поэтому можно указать любой правильный способ доработки исходной программы.)
1. x = 0, y = 0.5 – вообще не выдает никакого результата
2. Будем проверять принадлежность двум отрезкам (для определения границ воспользуемся оператором «и»), используя оператор «или»:
var x,y: real;
begin
readln(x,y);
if ((x >= -2) and (x <= 0) and (y >= x) and (y >= sqr(x)-2) and (y < -x)) or (x >= 0) and (x <= 2) and (y >= sqr(x)-2) and (y <= x) then
writeln('Принадлежит')
else
writeln('Не принадлежит');
end.
Демонстрационный вариант ЕГЭ 2010 г. ИНФОРМАТИКА и ИКТ, 11 класс
6.
Требовалось написать программу, которая вводит с клавиатуры координаты точки на плоскости (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) Укажите, как нужно доработать программу, чтобы не было случаев ее неправильной работы. (Это можно сделать несколькими способами, достаточно указать любой способ доработки исходной программы).
1. x = 0, y = 0 – вообще не выдает никакого результата
2. Посчитаем, какие значения может принимать x, приравняв уравнение прямой и окружности. Далее пропишем условие для y:
var x,y: real;
begin
readln(x,y);
if (x >= -2) and (x <= 2*sqrt(2)) and (y <= -x) and (y <= sqr(x) + sqr(y) - 4) then
writeln('Принадлежит')
else
writeln('Не принадлежит');
end.
Демонстрационный вариант ЕГЭ 2009 г. ИНФОРМАТИКА и ИКТ, 11 класс
7.
Требовалось написать программу, которая вводит с клавиатуры координаты точки на плоскости (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('не принадлежит') |
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. Например, x = 10, y = 0,8.
2. Поступаем аналогично предыдущим заданиям:
var x,y: real;
begin
readln(x,y);
if (x >= 0) and (x <= pi/2) and (y <= 1) and (y >= sin(x)) then
writeln('Принадлежит')
else
writeln('Не принадлежит');
end.
Вывод
Это последняя статья по данному заданию. Было любопытно увидеть вектор развития данного задания с 2009 по 2018. Можно заметить, что раньше у экзаменуемых было больше творческих возможностей, постепенно формат стал более стандартизированным.