Категория C4 • задача №1
Условие задачи
Дано:
после единых выпускных экзаменов по информатике в район пришла информация о том, какой ученик какой школы сколько набрал баллов. Эта информация в том же виде была разослана в школы.
Завуч школы № 50 решила наградить двух учащихся, которые лучше всех в школе сдали информатику.
Программа должна вывести на экран фамилии и имена этих учеников.
Если наибольший балл набрало больше двух человек – вывести количество таких учеников.
Если наибольший балл набрал один человек, а следующий балл набрало несколько человек - нужно вывести только фамилию и имя лучшего.
На вход программе сначала подаётся число учеников, сдававших экзамен. В каждой из следующих N строк находится информация об учениках в формате:
<Фамилия> <Имя> <Номер школы> <Количество баллов>, где
<Фамилия> - строка, состоящая не более чем из 30 символов без пробелов,
<Имя> - строка, состоящая не более, чем из 20 символов без пробелов,
<Номер школы> - целое число в диапазоне от 1 до 99,
<Количество баллов> - целое число в диапазоне от 1 до 100.
Найти:
напишите эффективную, в том числе и по используемой памяти, программу (укажите используемую версию языка программирования, например Borland Pascal 7.0), которая должна вывести на экран требуемую информацию. Известно, что информатику сдавало больше 5-ти учеников школы № 50.
Эти данные записаны через пробел, причём ровно один между каждой парой (то есть, всего по три пробела в каждой строке).
Пример входной строки:
Иванов Иван 50 87
Пример выходных данных:
Круглов Василий
Тарасова Дарья
Другой вариант выходных данных:
7
Третий вариант выходных данных:
Гусарский Илья
Решение
Начнем разбираться с задачей на конкретных данных, допустим экзамен сдавало 10 человек. Вся информация является вымышленной и все совпадения случайны.
Начнем построчный анализ входной информации.
Для корректного анализа потребуются вспомогательные "счетчики", а именно:
ФИО ученика, набравшего самый максимальный балл;
ФИО ученика, набравшего второй по максимальности балл;
балл, полученный текущим учеником;
значение самого максимального балла;
значение второго по максимальности балла;
количество учеников, набравших самый максимальный балл;
количество учеников, набравших второй по максимальности балл.
Ученик I : -
Ученик II : -
Текущий балл : -
Балл I : 0
Балл II : 0
Количество учеников I : 0
Количество учеников II: 0
Промежуточный вывод: запись под №1 пропускаем, так как требуется проводить анализ учеников только из школы №50, а текущий ученик из школы под номером 23.
Ученик I : Анюкова Елизавета
Ученик II : -
Текущий балл : 29
Балл I : 29
Балл II : 0
Количество учеников I : 1
Количество учеников II: 0
Промежуточный вывод: найден первый ученик из школы №50 и информация о текущем ученике записывается в счетчики.
Ученик I : Панкратов Илья
Ученик II : Анюкова Елизавета
Текущий балл : 84
Балл I : 84
Балл II : 29
Количество учеников I : 1
Количество учеников II: 1
Промежуточный вывод: ученик Панкратов Илья имеет более высокий балл, чем Анюкова Елизавета, следовательно, происходит переприсваивание информации, то есть, Панкратов Илья становится "первым" учеником, а Анюкова Елизавета переходит на "вторую" позицию.
Ученик I : Панкратов Илья
Ученик II : Анюкова Елизавета
Текущий балл : 84
Балл I : 84
Балл II : 29
Количество учеников I : 1
Количество учеников II: 1
Промежуточный вывод: запись под №4 пропускаем, так как требуется проводить анализ учеников только из школы №50, а текущий ученик из школы под номером 10. Значения всех "счетчиков" остаются без модификации.
Ученик I : Панкратов Илья
Ученик II : Оливье Марина
Текущий балл : 63
Балл I : 84
Балл II : 63
Количество учеников I : 1
Количество учеников II: 1
Промежуточный вывод: ученик Оливье Марина имеет более высокий балл, чем Анюкова Елизавета, следовательно, происходит переприсваивание информации, то есть, Оливье Марина становится "вторым" учеником, а Анюкова Елизавета покидает ранжирование.
Ученик I : Панкратов Илья
Ученик II : Оливье Марина
Текущий балл : 63
Балл I : 84
Балл II : 63
Количество учеников I : 1
Количество учеников II: 1
Промежуточный вывод: запись под №6 пропускаем, так как требуется проводить анализ учеников только из школы №50, а текущий ученик из школы под номером 6. Значения всех "счетчиков" остаются без модификации.
Ученик I : Петров Игорь
Ученик II : Панкратов Илья
Текущий балл : 92
Балл I : 92
Балл II : 84
Количество учеников I : 1
Количество учеников II: 1
Промежуточный вывод: ученик Петров Игорь имеет более высокий балл, чем Панкратов Илья, следовательно, происходит переприсваивание информации, то есть, Панкратов Илья становится "вторым" учеником, а Петров Игорь становится "лучшим" учеником на данный момент.
Ученик I : Петров Игорь
Ученик II : Панкратов Илья
Текущий балл : 84
Балл I : 92
Балл II : 84
Количество учеников I : 1
Количество учеников II: 2
Промежуточный вывод: текущий ученик Якимова Мария имеет аналогичный балл, как и второй по максимальности балл, полученный Панкратовым Ильей. Следовательно, производим увеличение счетчика, отвечающего за количество учеников, получивших второй по максимальности балл на единицу.
Ученик I : Петров Игорь
Ученик II : Володина Тамара
Текущий балл : 91
Балл I : 92
Балл II : 91
Количество учеников I : 1
Количество учеников II: 1
Промежуточный вывод: ученик Володина Тамара имеет более высокий балл, чем Панкратов Илья (и меньше, чем Петров Игорь), следовательно, происходит переприсваивание информации, то есть, Володина Тамара становится "вторым" учеником, а Панкратов Илья покидает ранжирование.
Ученик I : Петров Игорь
Ученик II : Володина Тамара
Текущий балл : 91
Балл I : 92
Балл II : 91
Количество учеников I : 1
Количество учеников II: 1
Промежуточный вывод: запись под №10 пропускаем, так как требуется проводить анализ учеников только из школы №50, а текущий ученик из школы под номером 21. Значения всех "счетчиков" остаются без модификации.
В итоге имеем:
Как видно из представленной таблицы, существует единственный ученик (Петров Игорь), набравший самый максимальный балл и существует единственный человек (Володина Тамара), набравший второй по максимальности балл.
В условии задачи было постулировано, что, если существует по одному ученику, набравшему максимальные баллы, то требуется вывести на экран информацию о них, то есть, для рассматриваемых данных ответ будет таким:
Петров Игорь
Володина Тамара
Рассмотрим реализацию программы на языке программирования Turbo Pascal 7.0 с подробными русифицированными комментариями:
program C4;
{раздел подключения модулей и сторонних расширений}
uses
{подключаем модуль crt – console run time. Данный модуль содержит специализированные подпрограммы для обработки текста, звука, клавиатурных событий}
crt;
{раздел объявления константных величин}
const
{поскольку требуется проводить анализ только учеников из школы 50}
NUMBER = 50;
{раздел декларации переменных}
var
{количество строк с информацией для анализа и обработки}
n : integer;
{хранит фамилию и имя текущего ученика}
currFio : string;
{хранит фамилию и имя ученика набравшего максимальный балл по школе}
fio1 : string;
{хранит фамилию и имя ученика набравшего второй по максимальности балл}
fio2 : string;
{количество учеников набравших самый максимальный балл по школе}
k1 : integer;
{количество учеников набравших второй по максимальности балл}
k2 : integer;
{максимальный балл, полученный учеником/ учениками по школе}
ball1 : integer;
{второй по максимальности балл, полученный по школе}
ball2 : integer;
{счетчик циклов}
i : integer;
{хранит введенный символ пользователем с клавиатуры}
ch : char
{номер школы, считанный с клавиатуры, текущей записи}
numberSchool : integer;
{значение полученного балла текущим учеником}
currBall : integer;
{главный блок программы}
begin
{очистка экрана от прошлых выводов}
clrscr;
{устанавливаем белый цвет тексту на дисплее}
textColor(WHITE);
{диалог пользователю о вводе количества записей для обработки}
write(‘Введите количество записей: ’);
{считывание с клавиатуры количества записей}
readln (n);
{происходит обнуление информации, поскольку ее обработка еще не начиналась}
k1 := 0;
k2 := 0;
fio1 := ‘ ’;
fio2 := ‘ ’;
ball1 := 0;
ball2 := 0;
{вставка пустой строки для повышения читабельности}
writeln;
{цикл со счетчиком, в котором происходит запрос информации от пользователя и, сразу же происходит обработка и анализ полученной информации}
for i := 1 to n do
begin
{посимвольно считываем фамилию текущего ученика и запоминаем ее}
currFio := ‘ ’;
repeat
read(ch);
currFio := currFio + ch;
until(ch = ‘ ’);
{посимвольно считываем имя текущего ученика и запоминаем его добавляя в конец ранее считанной фамилии}
repeat
read(ch);
currFio := currFio + ch;
until(ch = ‘ ’);
{считываем номер школы и балл набранный текущим учеником}
readln (numberSchool, currBall);
{вся обработка производится над учениками из школы номер 50}
if (numberSchool = NUMBER) then
begin
{если текущий балл больше по значению максимального балла среди всех учеников, то происходит переприсваивание. Характеристики ученика набравшего максимальный балл, становятся характеристиками ученика, набравшего второй по максимальности балл, а текущие характеристики присваиваются ученику набравшего максимальный балл}
if(currBall > ball1) then
begin
fio2 := fio1;
k2 := k1;
ball2 := ball1;
fio1 := currFio;
ball1 := currBall;
{ученик, получивший максимальный балл пока что ЕДИНСТВЕННЫЙ среди всех учеников}
k1 := 1;
end
else
{если текущий балл совпадает по значению с максимальным баллом среди всех учеников, то увеличивается количество учеников получивших максимальный балл на единицу и фамилия текущего ученика, присваивается взамен фамилии ученика, набравшего второй по максимальности балл}
if(currBall = ball1) then
begin
k1 := k1 + 1;
fio2 := currFio;
k2 := k1;
end
{если текущий балл меньше по значению максимального балла, но больше по значению чем второй по максимальности балл, то характеристики текущего ученика присваиваются характеристикам ученика, получившего второй по максимальности балл}
else
if(currBall > ball2) then
begin
k2 := 1;
ball2 := currBall;
fio2 := currFio;
end
else
{если текущий балл совпадает по значению со вторым максимальным баллом, то количество учеников, набравших второй по максимальности балл, увеличивается на единицу}
if(currBall = ball2) then
k2 := k2 + 1;
end;
end;
{перед печатью производим анализ: если количество учеников, набравших максимальный балл больше двух, то выпечатывается количество таких учеников}
if(k1 > 2) then
writeln(k1)
else
{если количество учеников, набравших максимальный балл равно одному и количество учеников, набравших второй по максимальности балл больше одного человека, то печатается только фамилия и имя ученика, получившего максимальный балл по школе}
if(k1 = 1) and (k2 > 1) then
writeln(fio1)
else
{во всех остальных вариантах визуализируются фамилии и имена учеников, набравших максимальный и второй по максимальности балл по школе номер 50}
begin
writeln(fio1);
writeln(fio2);
end;
{имитация задержки программы. Программа будет закрыта после нажатия произвольной клавиши на клавиатуре}
readkey;
{финализирующий оператор программы}
end.
Комментарии