Я бы про задачу С4 сказала, что здесь главное - придумать такую структуру данных (массив, множество, запись), при использовании которой программа становится эффективнее.
Приведу пример С4 из Демо версии 2008 года: На вход программе подаются сведения о сдаче экзаменов учениками
9-х классов некоторой средней школы. В первой строке сообщается количество учеников N, которое не меньше 10, но не превосходит 100, каждая из следующих N строк имеет следующий формат:
<Фамилия> <Имя> <оценки>,
где <Фамилия> – строка, состоящая не более чем из 20 символов,
<Имя> – строка, состоящая не более чем из 15 символов, <оценки> – через пробел три целых числа, соответствующие оценкам по пятибалльной системе. <Фамилия> и <Имя>, а также <Имя> и <оценки> разделены одним пробелом. Пример входной строки:
Иванов Петр 4 5 3
Требуется написать как можно более эффективную программу (укажите используемую версию языка программирования, например, Borland Pascal 7.0), которая будет выводить на экран фамилии и имена трех худших по среднему баллу учеников. Если среди остальных есть ученики, набравшие тот же средний балл, что и один из трех худших, то следует вывести и их фамилии и имена.
В прикрепленном файле вариант решения моего ученика (PascalABC.net). Дима придумал такую структуру данных - массив множеств. Только такая программа будет работать только в Паскале ABC.net. По-моему, программа эффективнее, чем предложенный вариант решения (там решается через записи). Если я ошибаюсь по поводу эффективности, то буду признательна, если кто-нибудь мне объяснит мою ошибку.
var
k: array[3..15] of set of string;
n,i,j,a,b,c: byte;
s: string;
begin
for i:=3 to 15 do k[i]:=[];
readln(n);
for i:=1 to n do
begin
readln(s);
a:=StrToInt(s[length(s)]);
b:=StrToInt(s[length(s)-2]);
c:=StrToInt(s[length(s)-4]);
delete(s,length(s)-5,6);
include(k[a+b+c],s);
end;
j:=0;
for i:=3 to 15 do
begin
if k[i]<>[] then begin
writeln(k[i]);
j:=j+1;
end;
if j=3 then break;
end;
end.
Мы с коллегами начали думать и об условии этой задачи, и о ее решении. Кого считать тремя худшими учениками? Допустим, что мы имеем на входе следующие данные:
6
Иванов Иван 2 2 2
Петров Петр 2 2 2
Сергеев Сергей 3 3 3
Андреев Андрей 3 3 3
Михайлов Михаил 4 4 4
Федоров Федор 4 4 4
Какие фамилии должно вывести решение?
Наши олимпиадники, "собаку съевшие на условиях и решениях", считают, что вывод такой:
Иванов Иван
Петров Петр
Сергеев Сергей
Андреев Андрей
А в примере решения в демо-тесте выводятся ВСЕ фамилии, что не правильно. :(
p.s. Ирина Александровна! Мне очень понравилось решение Вашего ученика, но оно страдает той же бедой - кого понимать под тремя худшими учениками? И с выводом результатов в этом решение не все ясно. Так ведь множество нельзя выводить? Задача проработает, если в каждом множестве одна фамилия, а если две, то вывод будет в одну строку без пробела. :(
Елена, в задаче привязка идет не к фамилии, а к среднему баллу, цитирую "выводить на экран фамилии и имена трех худших по среднему баллу учеников. Если среди остальных есть ученики, набравшие тот же средний балл, что и один из трех худших, то следует вывести и их фамилии и имена" . Т.е. правильный вывод должен содержать в данном случае всех учеников.
"Задача проработает, если в каждом множестве одна фамилия, а если две, то вывод будет в одну строку без пробела. :(" Элементы множества в Паскале АВС выводятся в строку с квадратных скобках, каждый элемент множества в апострофах и через запятую. В условии задачи не определен формат вывода, поэтому считаю, что данный вариант допустим.
Ирина, что Вы! Я совсем не хотела Вас обидеть! Я просто всех приглашаю к обсуждению. Ведь решения и в книжках по подготоке к ЕГЭ и в самих проверочных инструкциях далеки от эффективных. Порою они катастрофически неверны! Взять только задачу про "шахматную доску", это кошмар!!!
Получается, что если у Вас класс из 30-ти человек разбился на три группы по среднему баллу: 3, 4, 5. То выведется весь класс. Это неправильно. Худшими будут только те, кто имеет в среднем "три". Согласитесь! По житейски это так! И в формулировке задачи привязка как раз к фамилиям, а не к средним баллам. Мы эту задачу решали и на кафедре, и в центре олимпиадной подготовки (который подготовил два года назад чемпионов мира по программированию, а в этом году чемпионов России), так вот именно олимпиадники настаивают на том, что в моем примере выводится четыре фамилии, а не шесть. Они на этом (на нечетких формулировках) поднаторели. :)
Я это к чему - будьте осторожны. Эти задачи содержат тонкости, о которох даже авторы задач не догадываются.
А идея решения Вашего ребенка замечательно. Я смогла перевести его на Borland Pascal. Получилось красиво. :)
Ирина Александровна! Простите, опоздала с ответом на ваше личное сообщение. Была с ребятами в Лаборатории Касперского в Москве. Я смотрю Вы уже разобрались и все разместили. Спасибо, за программу элективного курса и за красивое решение задачи С4.Презентации можете прикреплять даже в комментариях на форуме или как ссылку, разместив предварительно в Scribd.
На вход программе подаются произвольно алфавитно-цифровые символы. Ввод этих символов заканчивается точкой.
Требуется написать программу, которая будет печатать последовательность строчных английских букв (“a”, “b”, … ”z”) из входной последовательности и частот их повторения. Печать должна происходить в алфавитном порядке.
Например, пусть на вход подаются следующие символы:
fhb5kbfыshfm.
В этом случае программа должна вывести
b2
f3
h2
k1
m1
s1
Эта задачка взята с сайта fipi.ru из открытого сегмента базы данных задач.
На вход программе подаются сведения о ячейках автоматической камеры хранения багажа. В первой строке задана текущая дата: через точку два целых числа, соответствующие дню (от 01 до 31 – ровно 2 символа) и месяцу (от 01 до 12 – ровно 2 символа). Во второй строке сообщается количество занятых ячеек N, которое не меньше 3, но не превосходит 1000. Каждая из следующих N строк имеет следующий формат: <номер ячейки> <дата сдачи багажа>, где <номер ячейки> – четырехзначное число, <дата сдачи багажа> – через точку два целых числа, соответствующие дню (от 01 до 31 – ровно 2 символа) и месяцу (от 01 до 12 – ровно 2 символа). Номер ячейки и дата сдачи багажа разделены одним пробелом. Сведения отсортированы в порядке номеров ячеек.
Время хранения багажа – трое суток. Требуется написать как можно более эффективную программу, которая выведет номера ячеек, в которых багаж хранится заведомо больше трех суток – то есть разница между датой сдачи багажа и текущей датой составляет 4 и более дней. Номера ячеек следует выводить в хронологическом порядке сдачи багажа.
Багаж мог сдаваться только в текущем или предыдущем месяце текущего календарного года (если текущий месяц январь, то данные о сдаче багажа в декабре прошлого года отсутствуют). Количество дней в каждом из месяцев текущего года следующее: январь – 31, февраль – 28, март – 31, апрель – 30, май – 31, июнь – 30, июль – 31, август – 31, сентябрь – 30, октябрь – 31, ноябрь – 30, декабрь – 31. Все входные данные корректны.
Пример входных данных:
04.06
3
1000 01.06
1001 31.05
2007 21.05
Результат работы программы для этого примера
2007
1001
На вход программы подаются фамилии и имена учеников. Известно, что общее количество учеников не превосходит 100.
В первой строке вводится количество учеников, принимавших участие в соревнованиях, N. Далее следуют N строк, имеющих следующий формат: <Фамилия> <Имя>. Здесь <Фамилия> - строка, состоящая не более чем из 20 символов; <Имя> - строка, состоящая не более чем из 15 символов; при этом <Фамилия> и <Имя> разделены одним пробелом.
Примеры входных строк:
Иванова Мария
Петров Сергей
Требуется написать программу, которая формирует и печатает уникальный логин для каждого ученика по следующему правилу: если фамилия встречается первый раз, то логин – это данная фамилия, если фамилия встречается второй раз, то логин – это фамилия, в конец которой приписывается число 2 и т.д.
Например, для входной последовательности
Иванова Мария
Петров Сергей
Бойцова Екатерина
Петров Иван
Иванова Наташа
будут сформированы следующие логины:
Иванова
Петров
Бойцова
Петров2
Иванова2
На вход программе подаются сведения об учениках некоторой средней школы. В первой строке сообщается количество учеников N, каждая из следующих N строк имеет следующий формат: <Фамилия> <Имя> <класс>, где <Фамилия> – строка, состоящая не более, чем из 20 символов, <Имя> – строка, состоящая не более, чем из 15 символов, <класс> – год обучения (от 1 до 12) и заглавная буква (от “А” до “Я”) без пробела. <Фамилия> и <Имя>, а также <Имя> <класс> разделены одним пробелом. Пример входной строки:
Иванов Петр 10Б
Требуется написать программу на языке Паскаль или Бейсик, которая будет выводить на экран информацию о параллелях (годе обучения) с наибольшим числом учеников. Программа должна выводить на экран в первой строке количество учеников в искомых параллелях, а во второй строке – в порядке возрастания номера этих параллелей через пробел. Например:
100
1 7 11
Я бы про задачу С4 сказала, что здесь главное - придумать такую структуру данных (массив, множество, запись), при использовании которой программа становится эффективнее.
Приведу пример С4 из Демо версии 2008 года: На вход программе подаются сведения о сдаче экзаменов учениками
9-х классов некоторой средней школы. В первой строке сообщается количество учеников N, которое не меньше 10, но не превосходит 100, каждая из следующих N строк имеет следующий формат:
<Фамилия> <Имя> <оценки>,
где <Фамилия> – строка, состоящая не более чем из 20 символов,
<Имя> – строка, состоящая не более чем из 15 символов, <оценки> – через пробел три целых числа, соответствующие оценкам по пятибалльной системе. <Фамилия> и <Имя>, а также <Имя> и <оценки> разделены одним пробелом. Пример входной строки:
Иванов Петр 4 5 3
Требуется написать как можно более эффективную программу (укажите используемую версию языка программирования, например, Borland Pascal 7.0), которая будет выводить на экран фамилии и имена трех худших по среднему баллу учеников. Если среди остальных есть ученики, набравшие тот же средний балл, что и один из трех худших, то следует вывести и их фамилии и имена.
В прикрепленном файле вариант решения моего ученика (PascalABC.net). Дима придумал такую структуру данных - массив множеств. Только такая программа будет работать только в Паскале ABC.net. По-моему, программа эффективнее, чем предложенный вариант решения (там решается через записи). Если я ошибаюсь по поводу эффективности, то буду признательна, если кто-нибудь мне объяснит мою ошибку.
var
k: array[3..15] of set of string;
n,i,j,a,b,c: byte;
s: string;
begin
for i:=3 to 15 do k[i]:=[];
readln(n);
for i:=1 to n do
begin
readln(s);
a:=StrToInt(s[length(s)]);
b:=StrToInt(s[length(s)-2]);
c:=StrToInt(s[length(s)-4]);
delete(s,length(s)-5,6);
include(k[a+b+c],s);
end;
j:=0;
for i:=3 to 15 do
begin
if k[i]<>[] then begin
writeln(k[i]);
j:=j+1;
end;
if j=3 then break;
end;
end.