Добавил:
Upload Опубликованный материал нарушает ваши авторские права? Сообщите нам.
Вуз: Предмет: Файл:
Скачиваний:
24
Добавлен:
19.05.2015
Размер:
719.36 Кб
Скачать

Var word: string;

c: char;

i, k, len: integer;

begin

word := '';

repeat

read(c); { чтение символа }

if c in ['a'..'z','A'..'Z'] then

word := word + c

else begin

if word <> '' then begin

len := Length(word);

{ обрабатываем слово }

for i:=1 to len do begin

k := Ord(word[i]) + len;

if word[i] in ['a'..'z'] then

if k > Ord('z') then k := k - 26;

if word[i] in ['A'..'Z'] then

if k > Ord('Z') then k := k - 26;

word[i] := Chr(k);

end;

{ вывод слова без перехода на новую строку}

write(word);

word := ''; { пустая строка }

end;

write(c); { вывод символа после слова }

end;

until c = '#';

writeln;

end.

  1. Для решения задачи нужно сначала прочитать все данные. Нас не интересуют фамилии, имена и номера школ, нужно только знать, сколько участников набрали определенное число баллов. Для этого заведем массив счетчиков count с индексами в интервале от 0 до 100, так что count[i] будет обозначать число участников экзамена, набравших i баллов. В начале массив нужно обнулить, а затем прочитать все данные:

{ обнуляем массив }

for i:=0 to 100 do count[i]:=0;

{ читаем количество строк}

readln(N);

for i:=1 to N do begin

{ пропускаем фамилию и имя}

repeat read(c) until c=' ';

repeat read(c) until c=' ';

readln(sch, ball); { читаем номер школы и балл ученика}

count[ball]:=count[ball]+1;

end;

Определяем 20% от всех участников:

M := N div 5;

и пытаемся найти такой балл i, что M участников получили балл не меньше i:

s:=0; i:=100;

while s < M do begin

s:=s+count[i];

i:=i-1;

end;

i := i + 1;

или так

s:=0; i:=101;

while s < M do begin

i:=i-1;

s:=s+count[i];

end;

Если после этого s = M, то ровно M участников получили балл i и выше, им ставится отличная отметка. Кроме того, «отлично» ставится в том случае, когда более 20% учеников набрали высший балл. Это значит, что s = count[i], то есть, сумма s в самом деле состоит из одного слагаемого. Поэтому

if (s = M) or (s = count[i]) then writeln(i)

else ...

Если ни один из этих вариантов не подошел, то участникам, набравшим i баллов, не будет поставлена отметка «отлично». Но вывести на экран i-1 в виде результата нельзя, потому что может быть так, что i-1 балл никто не набрал. Поэтому ищем первый балл, больший i, который набрал хотя бы один человек:

else begin

repeat

i:=i+1;

until count[i]<>0;

writeln(i);

end;

Вот полная программа:

Var count:array[0..100] of integer;

c: char;

I, n, sch, ball, m, s: integer;

begin

{ обнуляем массив }

for i:=0 to 100 do count[i]:=0;

{ читаем количество строк}

readln(N);

for i:=1 to N do begin

{ пропускаем фамилию и имя}

repeat read(c) until c=' ';

repeat read(c) until c=' ';

readln(sch,ball); { читаем номер школы и балл ученика}

count[ball]:=count[ball]+1;

end;

M := N div 5; {вычисляем 20% от количества учеников}

{ ищем минимальный балл этих 20% }

s := 0;

i:=101;

while s < M do begin

i:=i-1;

s:=s+count[i];

end;

{ вывод результата }

if (s = M) or (s = count[i]) then

{ i баллов – «отлично» }

writeln (i)

else begin

{ i баллов не «отлично» }

repeat

i:=i+1;

until count[i]<>0;

writeln(i);

end;

end.

  1. Во-первых, нас интересуют только цифры, остальные символы можно просто пропускать. Во-вторых, предполагается, что текст может быть достаточно длинный, так что читать его в массив (или строку) не нужно – в этом случае получится неоптимальная программа. Фактически для ответа на вопрос задачи нам нужно знать только количество цифр, поэтому достаточно выделить в памяти массив счетчиков с индексами от 0 до 9 и считать цифры:

num: array[0..9] of integer;

Кроме того, нам нужно узнать, есть ли в строке хотя бы одна цифра (чтобы вывести ответ «Да» или «Нет»). Для этого во время чтения будем считать найденные цифры в переменной count. В начале программы счетчики нужно обнулить:

for i:=0 to 9 do num[i] := 0;

count := 0;

При чтении проверяем очередной символ так: если его код находится между кодом цифры ‘0’ (код 48) и цифры ‘9’ (код 57), то это цифра. Так можно делать, потому что цифры во всех кодовых страницах стоят последовательно, одна за другой. Вот полный цикл чтения до точки:

repeat

read(c);

if ('0' <= c) and (c <= '9') then begin

k := Ord(c) - Ord('0');

num[k] := num[k] + 1;

count := count + 1;

end;

until c = '.';

Здесь используется цикл repeat, потому что хотя бы один символ необходимо прочитать. Чтобы найти номер нужного счетчика k, вычисляем разность между кодами прочитанного символа и цифры '0'.

Чтобы при выводе получилось максимальное число, нужно сначала выводить все девятки (их количество записано в num[9]), затем все восьмерки и т.д. до нуля:

for i:=9 downto 0 do

for k:=1 to num[i] do write(i);

Здесь используется оператор write, который не переходит на новую строку и выводит все цифры в одной строке.

Осталась одна проблема: если в строке есть только нули, нужно вывести только один ноль. Состояние «цифры есть, но все они – нули» записывается в виде условия

if (count = num[0]) and (num[0] > 0) then

num[0] := 1;

в этом случае в счетчик нулей записываем единицу. После этого будет выведен только один нуль.

Вот полная программа:

program qq;

Соседние файлы в папке ЕГЗ_2012_Поляков_май