Базовые алгоритмы: ExamBase2, ExamBase28
Группы заданий ExamBase и ExamFBase посвящены базовым алгоритмическим задачам,
включенным в кодификатор ЕГЭ по информатике. Процесс выполнения подобных заданий мы рассмотрим на примере
одной из простых задач, связанных с нахождением максимумов и минимумов из двух, трех или четырех чисел
без использования массивов и циклов.
Вначале решим задачу из группы ExamBase, а затем приведем решение аналогичной задачи из группы ExamFBase
(эти решения будут отличаться только способом ввода исходных данных).
ExamBase2°. На вход подаются три вещественных числа; числа расположены в одной строке.
Вывести вначале минимальное, а затем максимальное из них. Каждое число должно выводиться на новой строке
и снабжаться комментарием: «MIN=» для минимального, «MAX=»
для максимального.
Создание программы-заготовки и знакомство с заданием
Для создания программы-заготовки для данного задания надо, как обычно, воспользоваться
модулем PT4Load, введя в его окне имя задания: ExamBase2.
При выполнении задания в системе Lazarus созданная программа-заготовка будет иметь следующий вид:
{$mode delphi}{$H+}
program ExamBase2;
uses PT4Exam;
// Для ввода используйте процедуру Read или Readln
// Для вывода используйте процедуру Writeln,
// после выводимых чисел указывайте атрибуты форматирования :0:2
begin
Task('ExamBase2');
end.
После запуска программы на экране появится окно задачника с информацией
о том, что выполнен ознакомительный запуск программы.
Обсудим особенности программы-заготовки и окна задачника.
В программе-заготовке вместо модуля PT4
подключается модуль PT4Exam, специально предназначенный для использования при выполнении
заданий групп Exam. Данный модуль содержит реализацию процедуры Task,
инициализирующей задание, а также процедур, связанных с выводом данных в раздел отладки.
Подчеркнем, что процедуры, связанные с вводом исходных данных и выводом результатов, в него не включены.
Это обусловлено тем, что ввод-вывод при выполнении заданий групп Exam надо выполнять, используя
стандартные процедуры языка Pascal.
Основной особенностью окна задачника является то, что в разделе исходных данных отсутствуют данные,
выделенные желтым цветом (напомним, что желтый цвет используется для выделения данных, которые необходимо
вводить с помощью специальных процедур ввода задачника). Вместо этого в окне отображается
строка бирюзового цвета, содержащая числовые данные. Вид строки подчеркивает то обстоятельство,
что вводить данные требуется не с помощью специальных процедур ввода, имеющихся в задачнике,
а с помощью стандартных процедур языка Pascal. Отметим, что бирюзовый цвет используется в окне задачника
для отображения «внешних» данных (содержащихся в файлах или динамических структурах), доступ к которым
должен осуществляться с помощью стандартных средств используемого языка программирования.
Пример верного решения выделяется серым цветом
(в отличие от «настоящих» результатов, выведенных программой учащегося, которые, как и входные данные,
выделяются бирюзовым цветом), однако представление выходных данных совпадает с
представлением входных: это набор строк,
содержащих числовые данные (дополненные комментариями). Вид данных в разделе результатов показывает,
что для их вывода, как и для ввода исходных данных, необходимо использовать стандартные процедуры языка Pascal.
Чтобы обратить внимание на необходимость использования стандартных процедур языка Pascal
для ввода и вывода данных, соответствующая информация выводится в разделе отладки,
расположенном в нижней части окна задачника. Кроме того,
эта же информация указывается в виде комментария в начале текста программы-заготовки.
Ввод исходных данных и их обработка
Приступим к выполнению задания. В данном случае следует использовать алгоритм, не требующий
применения массивов, поэтому опишем три простые переменные вещественного типа и введем в них исходные данные:
{$mode delphi}{$H+}
program ExamBase2;
uses PT4Exam;
// Для ввода используйте процедуру Read или Readln
// Для вывода используйте процедуру Writeln,
// после выводимых чисел указывайте атрибуты форматирования :0:2
var
a, b, c: real;
begin
Task('ExamBase2');
Read(a, b, c);
end.
Мы воспользовались стандартной процедурой ввода Read, введя все три исходных числа за один ее вызов.
Этого же результата мы могли бы добиться и с помощью процедуры Readln:
Readln(a, b, c);
Заметим, что использование отдельных процедур Readln для ввода каждого числа приведет к ошибочному результату:
Readln(a);
Readln(b);
Readln(c);
В этом случае уже после ввода первого числа произойдет автоматический переход на следующую строку
с исходными данными. Поэтому оставшиеся в первой строке числа будут пропущены, а поскольку
во второй строке «ничего нет» (входной поток состоит из единственной строки),
в переменные b и c будут записаны нулевые значения.
Приведенный пример показывает, что при организации ввода данных в заданиях групп Exam необходимо учитывать особенности
стандартных процедур Read и Readln.
При запуске приведенного выше варианта программы вид окна не изменится, поскольку мы не вывели никаких данных.
В заданиях групп Exam запуск программы считается ознакомительным до тех пор, пока программа не выведет
хотя бы один элемент результирующих данных. Кроме того, задачник не контролирует,
каким образом программа читает исходные данные (например, мы могли бы ввести всю исходную строку
в переменную типа string, а затем «разобрать» эту строку, выделив из нее три числа
и преобразовав их к типу real). Отмеченные особенности характерны именно для заданий групп Exam,
в которых для ввода данных не используются специальные средства задачника.
Реализуем алгоритм нахождения минимального и максимального элемента. Для этого опишем еще две
переменные min и max типа real и добавим в конец программы следующие операторы:
if a < b then
begin
min := a;
max := b;
end
else
begin
min := b;
max := a;
end;
if c < min then
min := c
else
if c > max then
max := c;
Таким образом, для одновременного нахождения минимального и максимального из трех чисел требуется
не более трех операций сравнения и не более трех операций присваивания.
Вывод результатов и их форматирование
Осталось вывести полученные результаты. Вывод, как и ввод, следует выполнять с помощью стандартных процедур
языка Pascal, учитывая их особенности.
Вначале, в качестве примера, организуем вывод, не соответствующий условиям задачи. Для этого добавим в конец программы
следующий оператор:
Writeln(min, max);
Приведем вид окна задачника при запуске полученной программы:
Мы видим, что минимум и максимум найдены правильно, однако выведены не в том формате,
который требовался (требуемый формат приводится в разделе с примером верного решения).
Мы допустили при выводе три ошибки: во-первых, вывели оба числа в одной строке, во-вторых,
не снабдили числа комментариями и, в-третьих, не настроили их отображение в формате
с двумя фиксированными дробными знаками.
Для исправления первых двух ошибок достаточно изменить вывод следующим образом:
Writeln('MIN=', min);
Writeln('MAX=', max);
Однако в этом случае числа по-прежнему будут отображаться в формате с плавающей точкой (поскольку такой
формат используется по умолчанию в варианте языка Pascal для системы Lazarus).
Для того чтобы отобразить числа в формате с фиксированной точкой, проще всего использовать
атрибуты форматирования, начинающиеся с символа «:» (двоеточие):
Writeln('MIN=', min:0:2);
Writeln('MAX=', max:0:2);
Первый атрибут определяет ширину поля вывода (если ширина равна 0, то используется минимально
необходимое поле вывода). Наличие второго атрибута (допустимого только для вещественных чисел) означает,
что число надо вывести в формате с фиксированной точкой, причем его значение равно количеству дробных знаков.
Обратите внимание на то, что в разделе отладки и в начальных комментариях к программе-заготовке
содержится информация о том, какие атрибуты форматирования надо использовать при выводе полученных результатов.
После проверки исправленной программы на девяти наборах тестовых данных будет выведено сообщение
о том, что задание выполнено:
В случае успешного прохождения тестового испытания в окно задачника не включается
раздел с примером верного решения, поскольку данные этого раздела совпадают
с результатами, полученными программой.
Вариант задания с файловым вводом
Поскольку при компьютерном проведении ЕГЭ по информатике в задачах на разработку программ
обычно требуется читать исходные данные из текстовых файлов, в задачник PT for Exam версии 3.0
были добавлены группы заданий, в которых ввод исходных данных требуется выполнять аналогичным способом.
Имена этих групп начинаются с префикса ExamF (символ F указывает на то, что исходные данные надо вводить из файла).
Соответствующая группа заданий для изучения базовых алгоритмов имеет имя ExamFBase.
Опишем особенности решения задач из этой группы на примере задачи ExamFBase2.
Созданная программа-заготовка для ExamFBase2 будет иметь следующий вид:
{$mode delphi}{$H+}
program ExamFBase2;
uses PT4ExamTasks;
// Исходные данные следует вводить с помощью процедур файлового ввода.
// Для вывода используйте процедуру Writeln,
// после выводимых чисел указывайте атрибуты форматирования :0:2
var filename: string;
begin
Task('ExamFBase2');
filename := GetString; // имя исходного файла
end.
После запуска программы на экране появится окно задачника.
Решение задачи с использованием файлового ввода
Сразу приведем пример правильного решения задачи ExamFBase2.
Оно отличается от решения задачи ExamBase2 только начальной частью, в которой
необходимо открыть исходный файл с именем filename,
прочесть из него требуемые данные и закрыть этот файл.
{$mode delphi}{$H+}
program ExamFBase2;
uses PT4ExamTasks;
// Исходные данные следует вводить с помощью процедур файлового ввода.
// Для вывода используйте процедуру Writeln,
// после выводимых чисел указывайте атрибуты форматирования :0:2
var
a, b, c, min, max : real;
f : text;
filename : string;
begin
Task('ExamFBase2');
filename := GetString; // имя исходного файла
Assign(f, filename);
Reset(f);
Read(f, a, b, c);
Close(f);
if a < b then
begin
min := a;
max := b;
end
else
begin
min := b;
max := a;
end;
if c < min then
min := c
else
if c > max then
max := c;
Writeln('MIN=', min:0:2);
Writeln('MAX=', max:0:2);
end.
После проверки программы на девяти наборах тестовых данных будет выведено сообщение о том, что задание выполнено:
Ввод и вывод массивов
Рассмотрим еще одно задание группы ExamBase, особенностью которого является вывод в качестве результата
элементов двумерного массива.
ExamBase28°. На вход в первой строке подаются два целых положительных числа M и N,
во второй строке — вещественное число D, а в третьей строке — набор из M вещественных чисел.
Сформировать и вывести двумерный вещественный массив размера M × N, у которого первый
столбец совпадает с исходным набором чисел, а элементы каждого следующего столбца равны сумме соответствующего
элемента предыдущего столбца и числа D (в результате каждая строка массива будет содержать
элементы арифметической прогрессии). Каждую строку элементов массива выводить на новой экранной строке,
для каждого числа отводить 7 экранных позиций.
При запуске программы-заготовки, созданной для этого задания, окно задачника примет следующий вид:
Анализируя исходные данные, можно заметить, что полученная матрица должна иметь 8 строк, тогда как
на экране отображаются только первые пять.
Это связано с тем, что по умолчанию используется режим «сокращенного» отображения данных, при котором
на экране выводится только несколько начальных строк. Признаком того, что имеются данные,
не выведенные на экране, является многоточие, расположенное в нижней части того раздела,
в котором показаны не все данные. Кроме того, в режиме сокращенного отображения
окно задачника содержит кнопку,
которая отображается в правом верхнем углу раздела исходных данных
(на этой кнопке изображается стилизованная стрелка, направленная вниз).
Для вывода всех данных достаточно нажать эту кнопку; можно также нажать клавишу [Ins] или выполнить
двойной щелчок мышью в любом месте раздела с данными задания (кроме раздела, содержащего формулировку).
Если выполнить эти действия для нашего окна, то оно изменится следующим образом:
Повторный двойной щелчок мышью, нажатие клавиши [Ins] или кнопки (на которой в данной ситуации будет отображаться
стрелка, направленная вверх см. рисунок) восстанавливает сокращенное
отображение данных. Заметим, что в режиме сокращенного отображения нумеруется только первая строка данных,
а в режиме полного отображения нумерацией снабжаются все строки.
Дополнительные возможности, связанные с просмотром
данных большого размера, описываются в разделе, посвященном задачам повышенной сложности.
Если закрыть окно задачника, находясь в режиме отображения всех данных,
то при последующих запусках программы окно будет сразу отображаться в этом режиме.
Приведем вариант правильного решения данной задачи (в этом варианте учитывается, что результирующий
двумерный массив имеет не более 20 строк и столбцов; соответствующее условие приведено в
преамбуле к описанию
группы ExamBase):
{$mode delphi}{$H+}
program ExamBase28;
uses PT4Exam;
// Для ввода используйте процедуру Read или Readln
// Для вывода используйте процедуры Write и Writeln,
// после выводимого числа указывайте атрибуты форматирования :7:2
var
m, n, i, j: integer;
d: real;
a: array[1..20, 1..20] of real;
begin
Task('ExamBase28');
Readln(m, n, d);
for i := 1 to m do
Read(a[i, 1]);
for j := 2 to n do
for i := 1 to m do
a[i, j] := a[i, j - 1] + d;
for i := 1 to m do
begin
for j := 1 to n do
Write(a[i, j]:7:2);
Writeln;
end;
end.
В приведенном решении следует обратить особое внимание на организацию ввода-вывода.
Укажем две особенности, связанные с вводом. Во-первых, несмотря
на то что по условию число d находится во второй строке, мы смогли включить его в один список с
предшествующими числами m и n (поскольку при чтении числовых данных переход на новую строку выполняется
автоматически). Во-вторых, при чтении элементов исходного набора необходимо использовать вариант
процедуры Read без суффикса «ln», чтобы не пропустить оставшиеся в этой строке числа.
При выводе полученного двумерного массива необходимо обеспечить его правильное форматирование:
каждый элемент должен выводиться на семи экранных позициях с двумя дробными знаками и, кроме того,
каждая строка массива должна выводиться на новой экранной строке. Это достигается за счет использования
соответствующих атрибутов форматирования и явного перехода на новую строку с помощью процедуры
Writeln без параметров.
Информация о том, как выполнить правильное форматирование выходных данных, содержится
в комментариях к программе-заготовке и в разделе отладки окна задачника.
Заметим, что начиная с версии 2.2 задачника PT for Exam, при решении задач можно использовать процедуры Show и ShowLine из
базового задачника Programming Taskbook, отображающие требуемые данные в специальном разделе отладки окна задачника.
Описание отладочных возможностей задачника приводится на вкладке «Отладка» в окне «Информация»,
которое можно вызвать из окна задачника, нажав клавишу F1.
Например, в среде Free Pascal Lazarus для вывода
в окне отладки содержимого матрицы a, полученной при решении задачи ExamBase28,
к программе достаточно добавить следующий фрагмент:
for i := 1 to m do
begin
for j := 1 to n do
Show(a[i,j], 7);
ShowLine;
end;
В результате при запуске программы в разделе отладки появится текст, аналогичный приведенному ниже:
1> 18.77 15.72 12.67 9.62 6.57 3.52 0.47 -2.58
2> 75.20 72.15 69.10 66.05 63.00 59.95 56.90 53.85
3> 85.75 82.70 79.65 76.60 73.55 70.50 67.45 64.40
4> 22.75 19.70 16.65 13.60 10.55 7.50 4.45 1.40
5> 88.48 85.43 82.38 79.33 76.28 73.23 70.18 67.13
6> -5.27 -8.32 -11.37 -14.42 -17.47 -20.52 -23.57 -26.62
7> 1.65 -1.40 -4.45 -7.50 -10.55 -13.60 -16.65 -19.70
8> 89.94 86.89 83.84 80.79 77.74 74.69 71.64 68.59
В варианте задачника для языка PascalABC.NET для настройки ширины области вывода следует использовать
процедуру SetWidth, поэтому фрагмент, обеспечивающий отладочный вывод матрицы a,
примет следующий вид:
SetWidth(7);
for i := 1 to m do
begin
for j := 1 to n do
Show(a[i,j]);
ShowLine;
end;
Начиная с версии 4.19 базового электронного задачника Programming Taskbook,
средства отладочного вывода для языка PascalABC.NET были расширены таким образом, чтобы
упростить вывод сложных структур данных. Например, для вывода матрицы a достаточно использовать
единственный вызов процедуры Show (дополненный, при необходимости, командой настройки ширины области вывода):
SetWidth(7);
Show(a);
Однако необходимо учитывать, что при этом будут выведены все элементы матрицы,
в том числе и не использованные при решении задачи.
Решение с файловым вводом исходных данных
Приведем решение, в котором используется ввод данных из текстового файла
(соответствующая задача имеет имя ExamFBase28).
{$mode delphi}{$H+}
program ExamFBase28;
uses PT4ExamTasks;
// Исходные данные следует вводить с помощью процедур файлового ввода.
// Для вывода используйте процедуры Write и Writeln,
// после выводимого числа указывайте атрибуты форматирования :7:2
var
filename: string;
f : text;
m, n, i, j: integer;
d: real;
a: array[1..20, 1..20] of real;
begin
Task('ExamFBase28');
filename := GetString; // имя исходного файла
Assign(f, filename);
Reset(f);
Readln(f, m, n, d);
for i := 1 to m do
Read(f, a[i, 1]);
Close(f);
for j := 2 to n do
for i := 1 to m do
a[i, j] := a[i, j - 1] + d;
for i := 1 to m do
begin
for j := 1 to n do
Write(a[i, j]:7:2);
Writeln;
end;
end.
После проверки программы на девяти наборах тестовых данных будет выведено сообщение о том, что задание выполнено:
|