Задачи демоверсий ЕГЭ
1 . На вход программы подаются сведения о сдаче экзаменов учениками 9-х классов некоторой средней школы.
В первой строке сообщается количество учеников N,
которое не меньше 10, но не превосходит 100, каждая из следующих строк имеет следующий формат: <Фамилия><Имя><Оценки>, где <Фамилия>- строка, содержащая не более 20 символов, <Имя> - строка состоящая не более чем из 15 символов,
<Оценки> - три целых числа через пробел, соответствующие оценкам по пятибалльной системе.
<Фамилия> и <Имя>, а также <Имя> и <Оценки> разделены одним пробелом. Пример входной строки:
Иванов Петр 4 5 4
Требуется написать программу, которая будет выводить на экран фамилии и имена трёх лучших по среднему баллу учеников. Если среди остальных
есть ученики, набравшие тот же средний балл, что и один из трех лучших, следует вывести и их фамилии и имена. Требуемые имена и фамилии
можно выводить в произвольном порядке.
Это задача демоверсии ЕГЭ по информатике 2009 г.
Сначала осуществим ввод данных в соответствии с требованиями условия задачи. При этом в массиве записей сохраняем фамилию, имя ученика и сумму его оценок. Сумма оценок - целое число, оно занимает меньше памяти, чем вещественное число, которое получится, если сохранять средний балл.
Далее сортируем данные по сумме оценок в порядке убывания до достижения параметром m значения больше 3. Параметр m изначально принимаем равным 1. При этом, параметр m увеличивается в процессе сортировки данных только, если меняется сумма оценок. Учитывается возможность того, что все ученики получили равное по сумме число баллов.
Program C4; Uses CRT; Type r_type=record fam:string[20]; nam:string[15]; sum:integer; {сумма оценок} end; Var x:array[1..100] of r_type; z:char; i,j,k,n,m:integer; a,b,c:1..5; {оценки} y:r_type; Begin ClrScr; {ввод n c проверкой 10<=n<=100} repeat write('n='); readln(n); until(n>=10) and (n<=100); {ввод данных} for i:=1 to n do begin ClrScr; with x[i] do begin fam:=''; repeat z:=readkey; write(z); fam:=fam+z; until z=' '; {пробел} nam:=''; repeat z:=readkey; write(z); nam:=nam+z; until z=' '; {пробел} readln(a,b,c); {оценки} sum:=a+b+c; {сумма оценок} end; end; {---завершение ввода данных---} ClrScr; {сортировка данных по с умме оценок} m:=1; i:=1; while (m<=3) and (i<=n) do begin k:=i; for j:=k to n do if x[j].sum>x[k].sum then k:=j; {вывод отсортированных данных} writeln (m,' ',x[k].fam,x[k] nam,' ',x[k].sum/3:4:1); y:=x[i]; x[i]:=x[k]; x[k]:=y; i:=i+1; {учет одинаковых сумм оценок, m увеличивается при разных суммах} if (k>1) and (x[k].sum
Второй вариант решения. Сумма оценок может меняться от 15 до 3. Для каждой возможной суммы оценок (параметр k), просматривая все записи в цикле for, ищем запись с такой же суммой, если находим, то осуществляем вывод и меняем флажок j с нулевого значения на 1. Далее уменьшаем значение возможной суммы оценок на 1 и, если флажок j=1, то увеличиваем счетчик мест m на 1.
k:=15; m:=1; ClrScr; while (k>=3) and (m<=3) do begin j:=0; for i:=1 to n do begin with x[i] do begin if (k=sum) then begin writeln(m,' ',fam:20,nam:15,sum/3:4:1); j:=1; end; end; end; k:=k-1; if j=1 then m:=m+1; end; readln; End.
2. Опишите на русском языке или на одном из языков программирования алгоритм поиска второго по величине (т.е. следующего по величине за максимальным) элемента в числовом массиве из 30 различных элементов..
В этой задаче в соответствии с условием не обязательно писать всю программу целиком, можно исключить ввод исходных данных. Удобно её оформить в виде процедуры
Учитываем, что в массиве может быть несколько элементов равных максимуму.
Используем идеи первого варианта первой задачи. Cортируем данные в порядке убывания до достижения параметром m значения равного 2. Параметр m изначально принимаем равным 1 При этом, параметр m увеличивается в процессе сортировки данных только, если меняется значение максимума. Если параметр m=2, то производим вывод найденного значения второго по величине максимума и выход из цикла. Учитываем возможность того, что все данные могут быть равны друг другу, т.е. возможность отсутствия второго максимума. При этом, параметр m увеличивается в процессе сортировки данных только, если меняется значение максимума. Если параметр m=2, то производим вывод найденного значения второго по величине максимума и выход из цикла. Учитываем возможность того, что все данные могут быть равны друг другу, т.е. возможность отсутствия второго максимума.
Program TPT6_2; Uses CRT; Const n=30; Type x_type=array [1..n] of integer; Procedure SecondMax(x:x_type); Var i,j,k,m,y:integer; Begin m:=1; i:=1; while (m<=2) and (i<=n) do begin k:=i; for j:=k to n do if x[j]>x[k] then k:=j; y:=x[i];x[i]:=x[k];x[k]:=y; if (i>1) and (x[i]<x[i-1]) then m:=m+1; if m=2 then begin writeln(x[i]); m:=3; end; i:=i+1; end; if m=1 then writeln('No second Max'); End; Procedure Input(var x:x_type); Var i:integer; Begin randomize; for i:=1 to n do x[i]:=random(20)+1; End; Procedure Sort(x:x_type; var z:x_type); Var i,j,k,y:integer; Begin z:=x; for i:=1 to n do begin k:=i; for j:=k to n do if z[j]>z[k] then k:=j; y:=z[i];z[i]:=z[k];z[k]:=y end; End; Procedure Output(x:x_type); Var i:integer; Begin Sort(x,x); for i:=1 to n do write(x[i]:3); End; Var x:x_type; Begin ClrScr; Input(x); Output(x); writeln; SecondMax(x); writeln;; readln End.В программе сортируем исходные данные для удобства восприятия полученного результата.
----------------------------------------------------------
3. На вход программы задаются 366 строк, которые содержат информацию о среднесуточной температуре всех дней 2004 года.
Формат каждой из строк следующий: сначала записана дата в формате dd.mm (на запись номера дня и номера месяца в числовом
формате отводится строго два символа, день от месяца отделен точкой), затем через пробел записано значение температуры -
число со знаком плюс или минус, с точностью до 1 цифры после десятичной точки.
Данная информация отсортирована по значению температуры, т.е. хронологический порядок нарушен.
Требуется написать программу, которая будет выводить на экран информацию о месяце (месяцах) среднемесячная температура у которого
(которых) наименее отклоняется от среднегодовой. В первой строке вывести среднегодовую температуру. Найденные значения для каждого из месяцев
следует выводить в отдельной строке в виде: номер месяца, значение среднемесячной температуры, отклонение от среднегодовой температуры.
В качестве типизированной константы объявим целочисленный массив days с количеством дней в месяцах високосного года. В качестве вещественного массива объявим массив tm (содержащий 12 элементов, по числу месяцев года), в который будем записывать среднемесячные значения температуры. Среднегодовую температуру сохраним в переменной ty. Значения даты и месяца будем записывать в строковую переменную dm, которая содержит ровно 5 символов (dd.mm). С помощью процедуры val переведем введенное строковое значение номера месяца в число m. Подстроку, содержащую два символа значения месяца, вырежем из строки dm с помощью функции copy.
Далее найдем номер месяца k с минимальным абсолютным отклонением среднемесячной температуры от среднегодовой. Выводим значение среднегодовой температуры. Ещё раз, просматривая массив tm, найдем все месяцы, где абсолютное значение отклонения среднемесячной температуры от среднегодовой почти равно (с погрешностью менее 0.1, так как сравнивать вещественные числа по строгому равенству нельзя) отклонению для найденного месяца k. Выводим сведения о этих месяцах.
Program C4; Uses CRT; Const days:array [1..12] of integer= (31,29,31,30,31,30,31,31,30, 31,30,31); Var tm:array [1..12] of real; t,ty:real; dm:string[5]; m:integer; err,i,k:integer; Begin ClrScr; ty:=0; for i:=1 to 12 do tm[i]:=0; for i:=1 to 366 do begin readln(dm,t); val(copy(dm,4,2),m,err); tm[m]:=tm[m]+t/days[m]; ty:=ty+t/366; end; k:=1; for i:=1 to 12 do if abs(tm[i]-ty) < abs(tm[k]-ty) then k:=i; writeln(ty:4:1); for i:=1 to 12 do if abs(tm[i]-tm[k])<.1 then writeln(i,' ',tm[i]:4:1,' ', abs(tm[i]-ty):4:1); readln; End.