Разбор задач части С
Задача С1 (Анализ предложенной программы)
Предлагается некоторая задача и программа, которая должна решать поставленную задачу, но содержит ошибки. Требуется определить результаты работы программы на различных входных данных, указать ошибки в программе и предложить правильное решение.
В прошлые годы предлагалась следующая задача: "Дана точка. Требуется определить попадание точки в область, заданную графиком". Ошибочно написанная программа, как правило, содержала вложенный оператор if с пропущенными else ветвями, а также содержала ошибки в условиях, характеризующих выделенную область.
Задача допускала множество вариаций. Можно было варьировать сложностью графика, используя гармонические функции, прямые и параболы, что влияло на сложность условий для выделения требуемой области. Необходимо было проводить анализ попадания точки в различные области графика. Даже для "натасканного" на подобные задачи ученика можно было предложить задачу, требующую понимания, а не только знания выученного шаблона.
В этом году предложенная задача была значительно упрощена. Задача состояла в разборе цифр десятичного числа. Для тех учеников, которые могут написать программу перевода десятичного числа в некоторую систему счисления, эта задача представляется элементарной. Выше эта задача была мною подробно рассмотрена. Задача не допускает особых вариаций. Ошибок особых там сделать просто негде. Можно, конечно, неверно записать условие в цикле while или в условном операторе, можно неверно написать оператор присваивания. Но все эти ошибки достаточно очевидны и легко исправляются. Тем не менее задача оценивается в 3 балла, что выше баллов по задаче С2, требующей программирования.
Рассмотрим один из вариантов задачи С1.
<<
Требовалось написать программу, при выполнении которой с клавиатуры считывается натуральное число N, не превосходящее 109, и выводится минимальная цифра этого числа. Программист торопился и написал программу неправильно. Вот вариант этой программы на Паскале:
var N: longint; digit, min_digit: integer; begin readln(N); min_digit := 0; while N > 0 do begin digit := N mod 10; if digit < min_digit then min_digit := digit; N := N div 10; end; writeln (digit); end.
Последовательно выполните следующее:
- Напишите, что выведет программа при вводе числа 862.
-
Найдите все ошибки в программе (их может быть одна или несколько). Для каждой ошибки:
- Выпишите строку, в которой сделана ошибка;
- Укажите, как исправить ошибку, - приведите правильный вариант строки.
Обратите внимание, что требуется найти ошибки в имеющейся программе, а не написать свою, возможно использующую другой алгоритм решения. Исправление ошибки должно затрагивать только строку, в которой находится ошибка.
>>
Задача сочетает разбор числа и нахождение минимума. Первая ошибка в программе – неверная инициализация переменной min_digit, хранящей минимальное значение. Вторая ошибка, которую скорее следует рассматривать как описку, связана с ошибкой вывода – на печать выводится не переменная min_digit, а переменная digit. Из-за первой ошибки условие в операторе if никогда выполняться не будет и переменная min_digit сохранит значение 0, полученное при инициализации. Из-за второй ошибки на печать будет выведено значение переменной digit, полученное на последнем шаге цикла - старшая цифра введенного числа.
Вот ответ, который следует дать для этой задачи:
- 8
-
Первая строка с ошибкой: min_digit := 0;
следует заменить: min_digit := 9;
-
Вторая строка с ошибкой: writeln (digit);
следует заменить: writeln (min_digit);
Большинство школьников, представивших решение этой задачи, давало правильный ответ на все три вопроса.