If not (p in podr) then begin
Стр 1 из 3Следующая ⇒ Case i of 2: tMonth[i]:= tMonth[i] / 29; 4,6,9,11: tMonth[i]:= tMonth[i] / 30; else tMonth[i]:= tMonth[i] / 31; end; tYear:= tYear / DAYS; Определить среднюю температуру по месяцам можно более красиво, если ввести массив констант – дней в каждом месяце: const days: array[1..12] of integer = (31,29,31,30,31,30,31,31,30,31,30,31); а потом сделать так: for i:=1 to 12 do tMonth[i]:= tMonth[i] / days[i]; но PascalABC, например, не поддерживает константные массивы. Теперь можно искать минимальное отклонение среднемесячной температуры от среднегодовой (важно! не забываем ставить модуль): min:= abs(tMonth[1] - tYear); for i:=2 to 12 do if abs(tMonth[i] - tYear) < min then min:= abs(tMonth[i] - tYear); Вывод результата очевиден, приведем сразу полную программу: const DAYS = 366; var tMonth: array[1..12] of real; i, month: integer; t, tYear, min: real; c: char; Begin for i:=1 to 12 do tMonth[i]:= 0; tYear:= 0; for i:=1 to DAYS do begin repeat read(c); until c = '.'; read (month); readln (t); tMonth[month]:= tMonth[month] + t; tYear:= tYear + t; end; for i:=1 to 12 do Case i of 2: tMonth[i]:= tMonth[i] / 29; 4,6,9,11: tMonth[i]:= tMonth[i] / 30; else tMonth[i]:= tMonth[i] / 31; end; tYear:= tYear / DAYS; min:= abs(tMonth[1] - tYear); for i:=2 to 12 do if abs(tMonth[i] - tYear) < min then min:= abs(tMonth[i] - tYear); writeln(tYear:0:2); for i:=1 to 12 do if abs(tMonth[i] - tYear) = min then writeln(i,' ',tMonth[i]:0:2,' ',tMonth[i]-tYear:0:2); End.
2) Здесь нужно считать одинаковые буквы, которых всего может быть 26 (от A до Z), причем строчные и заглавные буквы считаются вместе. Поэтому создаем массив счетчиков из 26 элементов: var count: array[1..26] of integer; Для удобства можно сразу коды букв A и a и записать в целые переменные cA:= Ord('A'); { заглавные } cAm:= Ord('a'); { строчные } В цикле, прочитав очередной символ, находим его код с помощью функции Ord, k:= Ord(c); Если это заглавная буква, то номер символа в алфавите вычисляется как k-cA+1, а для строчных k-cAm+1, соответствующий счетчик (элемент массива) нужно увеличить на 1: if ('A' <= c) and (c <= 'Z') then count[k-cA+1]:= count[k-cA+1] + 1;
if ('a' <= c) and (c <= 'z') then count[k-cAm+1]:= count[k-cAm+1] + 1; Когда все данные (до первой точки) введены, остается найти номер максимального элемента (переменная iMax), а затем вывести на экран соответствующий символ и количество повторений. Вот полная программа: var count:array[1..26] of integer; i, k, cA, cAm, iMax:integer; c: char; Begin cA:= Ord('A'); cAm:= Ord('a'); for i:=1 to 26 do count[i]:= 0; Repeat read(c); k:= Ord(c); if ('A' <= c) and (c <= 'Z') then count[k-cA+1]:= count[k-cA+1] + 1; if ('a' <= c) and (c <= 'z') then count[k-cAm+1]:= count[k-cAm+1] + 1; until c = '.'; iMax:= 1; for i:=2 to 26 do if count[i] > count[iMax] then iMax:= i; writeln(char(cA+iMax-1), ' ', count[iMax]); End. Возможно, несколько лучшее решение получится, если использовать массив счетчиков с символьными индексами (это можно сделать в Паскале, но не во всех языках программирования): var count:array['A'..'Z']of integer; После чтения символа удобно сразу привести его к верхнему регистру с помощью функции UpCase (преобразовать строчные буквы в заглавные): c:= UpCase(c); или (если в вашей версии Паскаля ее нет) вручную if c in ['a'..'z'] then c:= Char(Ord(c) - Ord('a') + Ord('A')); Если символ – латинская буква, то увеличиваем соответствующий счётчик: if c in ['A'..'Z'] then Inc(count[c]); Поиск максимума и вывод результата тоже упрощаются: iMax:='A'; for c:='B' to 'Z' do if count[c] > count[iMax] then iMax:=c; writeln(iMax,' ',count[iMax]); Отметим, что такое красивое решение возможно только в тех языках программирования, где есть массивы с симврольными индексами. Вот полная программа: var c, iMax:char; count: array['A'..'Z'] of integer; Begin for c:='A' to 'Z' do count[c]:=0; Repeat read(c); if c in ['a'..'z'] then c:= Char(Ord(c) - Ord('a') + Ord('A')); if c in ['A'..'Z'] then Inc(count[c]); until c = '.'; iMax:='A'; for c:='B' to 'Z' do if count[c] > count[iMax] then iMax:= c; writeln(iMax,' ',count[iMax]); End.
3) Все аналогично предыдущей задаче с двумя изменениями: заглавных букв нет и нужно вывести количество для всех букв. Код программы: var count:array[1..26] of integer; i, k, cA:integer; c: char; Begin cA:= Ord('a'); for i:=1 to 26 do count[i]:= 0; Repeat read(c); k:= Ord(c); if ('a' <= c) and (c <= 'z') then count[k-cA+1]:= count[k-cA+1] + 1; until c = '.'; for i:=1 to 26 do if count[i] > 0 then
writeln(char(cA+i-1), count[i]); End. Возможен и другой вариант (идею предложил Р. Басангов, МОУ «СОШ 3» г. Элиста), в котором используется массив с символьными индексами: count: array ['a'..'z'] of integer; Вот полное решение: var count: array ['a'..'z'] of integer; c: char; Begin for c:='a' to 'z' do count[c]:=0; Repeat read (c); if ('a' <= c) and (c <= 'z') then count[c]:= count[c] + 1; until c = '.'; for c:='a' to 'z' do if count[c]>0 then writeln(c, count[c]); End.
4) Заметим, что в этой задаче мы должны хранить в памяти все фамилии и считать, сколько раз они встретились. При этом имена нас не интересуют, поэтому можно выделить такой массив записей var Info: array[1..100] of record name: string; { фамилия } count: integer; { счетчик } end; Второе поле (счётчик count) показывает, какая это запись по счёту с той же самой фамилией. Например, если счётчик равен 5, раньше эта фамилия встречалась уже 4 раза. В этой задаче легко читать информацию целыми строками, а затем «вырезать» фамилию с помощью стандартных функций (фамилия окажется в строке s): readln(s); p:= Pos(' ', s); s:= Copy(s,1,p-1); Теперь проверяем, сколько таких фамилй уже есть в списке. Нужно в цикле просмотреть i-1 первых элементов массива Info (где i – номер обрабатываемой строки), если фамилия в очередной записи совпала с только что введенной, счетчик (переменная c) увеличивается на 1: c:= 1; for k:=1 to i-1 do if s = Info[k].name then c:= c + 1; Затем записываем фамилию ученика и значение счётчика в очередную запись: Info[i].name:= s; Info[i].count:= c; После обработки всех строк остается вывести на экран результат (список логинов). Если счётчик равен 1, фамилия встратилась в первый раз, и логин совпадает с фамилией. Если счётчик больше 1, его значение дописывается в конец фамилии (получаются логины вида «Иванов2», «Иванов3» и т.п.): for i:=1 to N do begin write(Info[i].name); if Info[i].count > 1 then write(Info[i].count); writeln; end; Вот полный код программы: var Info: array[1..100] of record name: string; count: integer; end; i, k, p, N, c: integer; s: string; exist: boolean; Begin readln(N); for i:=1 to N do begin readln(s); p:= Pos(' ', s); s:= Copy(s,1,p-1); c:= 1; for k:=1 to i-1 do if s = Info[k].name then c:= c + 1; Info[i].name:= s; Info[i].count:= c; end; for i:=1 to N do begin write(Info[i].name); if Info[i].count > 1 then write(Info[i].count); writeln; end; End.
5) Это упрощенный вариант второй задачи, подробно разобранной в основной части. Отличия: нужно найти максимум вместо минимума, и только один, а не три. const LIM = 250; var Info: array[1..LIM] of record
name: string; sum: integer; end; i, k, N, mark, max: integer; c: char; Begin readln(N); { ввод исходных данных } for i:=1 to N do begin Info[i].name:= ''; for k:=1 to 2 do Repeat read(c); Info[i].name:= Info[i].name + c; until c = ' '; Info[i].sum:= 0; for k:=1 to 3 do begin read(mark); Info[i].sum:= Info[i].sum + mark; end; readln; end; { поиск максимума} max:= Info[1].sum; for i:=2 to N do if Info[i].sum > max then max:= Info[i].sum; { вывод результата } for i:=1 to N do if Info[i].sum = max then writeln(Info[i].name); End.
Возможен другой вариант решения (А.С. Абрамов, лицей при РГСУ, г. Воронеж), основанный на следующей идее: в массив записываются фамилии только тех участников, которые имеют суммарный балл, равный максимальному на данный момент; если максимум меняется, возвращаемся к 1-му элементу массива и следующую «цепочку» максимумов записываем поверх предыдущей. Обработка данных выполняется сразу при вводе, отдельный поиск максимума не требуется. Целая переменная count будет обозначать количество найденных участников с максимальным баллом. В переменной max будем хранить максимальный (на данный момент) результат, а в переменной ball накапливать сумму баллов очередного участника. Тогда алгоритм обработки выглядит так (переменная s содержит фамилию и имя): if ball > max then begin { новый максимум } count:= 1; max:= ball; names[1]:= s; End Else if ball = max then begin { еще один участник в списке } count:= count + 1; names[count]:= s; end; Вот полная программа: const LIM = 250; var names: array[1..LIM] of string; i, k, N, ball, mark, max, count: integer; s: string; c: char; Begin readln(N); { ввод количества участников } max:= 0; count:=0; { ввод данных в цикле } for i:=1 to N do begin s:= ''; for k:=1 to 2 do { читаем фамилию и имя } Repeat read(c); s:= s + c; until c = ' '; { считываем и суммируем баллы } ball:= 0; for k:=1 to 3 do begin read(mark); ball:= ball + mark; end; readln; { ищем участников с максимальлным баллом } if ball > max then begin count:= 1; max:= ball; names[1]:= s; End Else if ball = max then begin count:= count + 1; names[count]:= s; end; end; { вывод результата } for i:=1 to count do writeln(names[i]); End.
6) Это вариант второй задачи, подробно разобранной в основной части. Отличия: нужно найти максимум вместо минимума, сумма складывается из четырех оценок. const LIM = 100; var Info: array[1..LIM] of record name: string; sum: integer;
end; i, k, N, mark, max1, max2, max3: integer; c: char; Begin readln(N); { ввод исходных данных } for i:=1 to N do begin Info[i].name:= ''; for k:=1 to 2 do Repeat read(c); Info[i].name:= Info[i].name + c; until c = ' '; Info[i].sum:= 0; for k:=1 to 4 do begin read(mark); Info[i].sum:= Info[i].sum + mark; end; readln; end; { поиск трех максимальных } max1:= 0; max2:= 0; max3:= 0; for i:=1 to N do begin if Info[i].sum > max1 then begin max3:= max2; max2:= max1; max1:= Info[i].sum; End else if Info[i].sum > max2 then begin max3:= max2; max2:= Info[i].sum; End else if Info[i].sum > max3 then max3:= Info[i].sum; end; { вывод результата } for i:=1 to N do if Info[i].sum >= max3 then writeln(Info[i].name); End.
7) Особенность этой задачи в том, что фамилии на выходе нужно отсортировать. «Школьные» сортировки имеют сложность s:= ''; for k:=1 to 2 do Repeat read(c); s:= s + c; until c = ' '; Теперь читаем два числа, readln(mark1, mark2); Учитывая, что до конца строки больше нет данных, используем оператор readln, а не read. Если хотя бы одна из оценок меньше 30, увеличиваем счетчик «неудачников» (переменная count) и записываем фамилию и имя (из переменной s) в элемент массива name с номером count: if (mark1 < 30) or (mark2 < 30) then begin count:= count + 1; name[count]:= s; end; После чтения всех данных массив фамилий «неудачников» нужно отсортировать, здесь мы используем простейший метод – классический «пузырек». Не забываем, что нужно сортировать не все N строк в массиве name, а только count (столько, сколько нашли «неудачников»): for i:=1 to count-1 do for k:=count-1 downto i do if name[k] > name[k+1] then begin s:= name[k]; name[k]:= name[k+1]; name[k+1]:= s; end; Вот полная программа: const LIM = 500; var name: array[1..LIM] of string; i, k, count, mark1, mark2, N: integer; c: char; s: string; Begin readln(N); { ввод исходных данных } count:= 0; for i:=1 to N do begin s:= ''; for k:=1 to 2 do Repeat read(c); s:= s + c; until c = ' '; readln(mark1, mark2); if (mark1 < 30) or (mark2 < 30) then begin count:= count + 1; name[count]:= s; end; end; { сортировка } for i:=1 to count-1 do for k:=count-1 downto i do if name[k] > name[k+1] then begin s:= name[k]; name[k]:= name[k+1]; name[k+1]:= s; end; { вывод результата } for i:=1 to count do writeln(name[i]); End.
8) Так как номера телефонов подразделений отличаются только двумя последними цифрами, задача сводится к тому, чтобы подсчитать, сколько различных чисел (номеров подразделений) встречается в этой последней части. Их может быть не более 100 (от 0 до 99), поэтому вводим массив из 100 элементов: var podr: array[1..100] of integer; Количество найденных разных подразделений будем хранить в целой переменной count (это счетчик, в начале в него нужно записать 0). Нас не интересуют фамилии и имена сотрудников, а также их полные телефоны. Поэтому при чтении строки пропускаем все символы до второго знака «–» включительно:
for k:=1 to 2 do Repeat read(c); until c = '-'; затем читаем номер подразделения в целую переменную p и проверяем, нет ли его в массиве podr (если есть – логическая переменная exist устанавливается в True): for k:= 1 to count do if podr[k] = p then begin exist:= True; break; end; С помощью оператора break досрочно выходим из цикла, если прочитанный номер уже есть в массиве. Если номер не нашли, увеличиваем счетчик и сохраняем этот номер в очередном элементе массива: If not exist then begin count:= count + 1; podr[count]:= p; end; После этого остается разделить общее число сотрудников N на количество подразделений. Вот полная программа: var podr: array[1..100] of integer; i, k, p, count, N: integer; c: char; exist: boolean; av: real; Begin readln(N); { ввод исходных данных } count:= 0; for i:=1 to N do begin for k:=1 to 2 do repeat read(c); until c = '-'; readln(p); exist:= False; for k:= 1 to count do if podr[k] = p then begin exist:= True; break; end; If not exist then begin count:= count + 1; podr[count]:= p; end; end; { вывод результата } av:= N / count; writeln(av:0:2); End. Еще одно, более красивое решение этой задачи, предложила Л.Б. Кулагина (ФМЛ № 239, г. Санкт-Петербург). Идея заключается в том, чтобы создать массив логических значений (по количеству возможных подразделений), сначала в каждый его элемент записать false и при чтении номера подразделения в соответствующий элемент записывать true (нашли этот номер). В конце программы для определения количества подразделений останется подсчитать, сколько элементов массива имеют значение true. var podr: array[0..99] of boolean; i, k, p, count, N: integer; c: char; av: real; Begin readln(N); { ввод исходных данных } for i:=0 to 99 do podr[i]:= False; { еще ничего не нашли } for i:=1 to N do begin for k:=1 to 2 do repeat read(c); until c = '-'; readln(p); podr[p]:= True; end; count:= 0; { считаем найденные подразделения } for i:=0 to 99 do if podr[i] then count:= count + 1; { вывод результата } av:= N / count; writeln(av:0:2); End. Если нет желания работать с логическим массивом, можно вполне обойтись целочисленным. В этом случае в самом начале в его элементы нужно записать нули (вместо False). Целочисленный массив позволит решить подобную задачу в том случае, если нам нужно будет знать количество сотрудников в каждом подразделении отдельно, тогда после чтения номера подразделения нужно увеличить соответствующий элемент массива, который является счетчиком: podr[p]:= podr[p] + 1; Немного изменится и подсчет количества подразделений: for i:=0 to 99 do if podr[i] > 0 then count:= count + 1; Существует еще один способ решения, который в данном случае, по-видимому, и является оптимальным. Однако в нем используются множества, которые в основном школьном курсе чаще всего не изучаются. Множество (англ. set) может включать некоторое (заранее неизвестное, а отличие от массива) количество элементов. В Паскале элементами множества могут быть целые числа от 0 до 255 или символы (точнее, коды символов). В данном случае код подразделения – целое число от 0 до 99, поэтому множество можно объявить так: var podr: set of 0..99; или так: var podr: set of byte; Во втором случае в множество могу входить любые числа от 0 до 255. Когда мы прочитали номер подразделения в переменную p, нужно проверить, входит ли это число во множество. Если входит, то ничего делать не требуется, а если не входит, нужно добавить его к множеству: if not (p in podr) then begin podr:= podr + [p]; { добавить к множеству } count:= count + 1; { увеличить счетчик подразделений } end; Запись [p] обозначает множество из одного элемента, а знак «плюс» – объединение множеств. Кроме того, нужно увеличить счетчик подразделений count (поскольку нет простого способа сразу определить количество элементов множества). var podr: set of 0..99; p: byte; i, k, N, count: integer; c: char; av: real; Begin podr:= []; count:= 0; { ввод исходных данных } readln(N); for i:=1 to N do begin for k:=1 to 2 do repeat read(c); until c = '-'; readln(p);
Воспользуйтесь поиском по сайту: ![]() ©2015 - 2025 megalektsii.ru Все авторские права принадлежат авторам лекционных материалов. Обратная связь с нами...
|