Главная | Обратная связь | Поможем написать вашу работу!
МегаЛекции

Как правильно понимать условие?




1) как и в предыдущей задаче, данные «подаются на вход программе», то есть, их можно читать с помощью операторов read (readln), предполагая, что кто-то вводит эти данные с клавиатуры вручную

2) «количество учеников не меньше 10, но не превосходит 100», здесь только вторая часть – полезная информация, она намекает на то, что придется все введенные данные одновременно держать в памяти, выделив массив (или массивы) размером 100 элементов

3) сказано, что фамилия имеет длину не более 20 символов, а имя – не более 15; здесь, по сути, важно лишь то, что фамилия и имя (вместе) занимают меньше 255 символов, то есть, «влезут» в стандартное ограничение (255 символов) для типа string в классических версиях Паскаля

4) после фамилии и имени записаны три оценки (а не одно число, как в прошлой задаче), причем по условию нас НЕ интересуют эти числа, а интересует только средний балл каждого ученика;

5) важно! средний балл – это вещественное число (может иметь дробную часть), тут уже стоит задуматься: все задачи обычно составляются так, чтобы они решались «хорошо», в то же время операции с дробными числами (почти) всегда выполняются с ошибками, поскольку большинство вещественных чисел нельзя точно (стандартными методами) представить в памяти реального компьютера

6) следующий шаг к правильному решению: поскольку число оценок у всех учеников одинаковое, средний балл для каждого это сумма его оценок, деленная на 3; поэтому вместо среднего балла мы можем сравнивать суммы баллов – целые числа!

7) требуется вывести фамилии и имена (баллы не нужны!) трех худших учеников, причем их может быть и больше, если несколько «худших» набрали одинаковую сумму баллов

8) если бы требовался один худший – все решается поиском по массиву; первая идея – найти самого худшего (1 проход), затем – 2-ого с конца (еще 1 проход), и, наконец, 3-его (всего три прохода по массиву)

9) это не лучший вариант (на экзамене будут сняты баллы) по двум причинам:

o в таком методе решения три прохода по массиву, а в самом деле достаточно одного (см. далее), значит, программа неэффективна

o непонятно, что делать в том случае, если худших – больше трех (в предельном случае – вообще все!) – за это также снимут баллы (программа работает не для всех вариантой входных данных)

10) возникает следующий вариант – отсортировать массив про возрастанию суммы (и, следовательно, среднего балла), одновременно переставляя имена и фамилии, а затем вывести самых худших, которые после сортировки окажутся в начале массива

11) этот вариант тоже плох, потому что программа неэффективна; «школьные» алгоритмы сортировки (метод «пузырька», метод выбора) имеют сложность , а надо попытаться найти метод со сложностью

Решение (общий подход):

1) сначала составим программу в самом общем виде на псевдокоде, чтобы определить ее основные блоки, а потом будем их постепенно «расшифровывать» через операторы языка программирования:

{ читаем все данные и запоминаем их }

{ находим три худших результата }

{ выводим фамилии и имена тех, чей результат меньше или

равен «третьему худшему» }

2) до того, как начать писать «нормальный» код, нужно определить, как хранить данные; в данном случае нужно запомнить несколько данных по каждому ученику, их удобнее объединить в запись с двумя полями (фамилия-имя и сумма баллов); таких записей нужно выделить в памяти не менее 100 (по условию), то есть, массив из 100 элементов:

const LIM=100;

var Info: array[1..LIM] of record

name: string;

sum: integer;

end;

Чтение данных:

3) после того, как мы прочитали фактическое число учеников N, в цикле считываем и расшифровываем информацию о них, сохраняя все данные в структурах

for i:=1 to N do begin

{ считываем строку данных }

Info[i].name:= { фамилия и имя };

Info[i].sum:= { сумма баллов };

end;

4) здесь, в принципе, можно использовать тот же подход, что и в первой задаче – читаем строку целиком, затем «разбираем» ее на части с помощью стандартных функций – однако, для разнообразия, мы используем другой подход – будем читать информацию посимвольно, то есть, считывая по одному символу в переменную c типа char;

5) сначала в поле name очередной структуры записываем пустую строку '' (в которой нет ни одного символа, длина равна нулю)

Info[i].name:= ''; { пустая строка }

6) затем считываем символы фамилии и сразу приписываем их в конец поля name:

Repeat

read (c);

Info[i].name:= Info[i].name + c;

until c = ' '; { пока не прочитали пробел }

7) затем также читаем из входного потока имя, до пробела, и записываем его в конец того же поля name:

Repeat

read (c);

Info[i].name:= Info[i].name + c;

until c = ' '; { пока не прочитали пробел }

заметьте, что эти два цикла одинаковы, поэтому ввод имени и фамилии можно записать в виде вложенного цикла так:

Info[i].name:= ''; { пустая строка }

for k:=1 to 2 do

Repeat

read (c);

Info[i].name:= Info[i].name + c;

until c = ' '; { пока не прочитали пробел }

8) важно! обратите внимание, что для организации внутреннего цикла используется другая переменная, k (а не i, потому что i – переменная главного цикла, она обозначает номер текущего ученика)

9) теперь во входном потоке остались три числа, которые мы можем последовательно считывать в целую переменную mark, а затем – добавлять к полю Info[i].sum:

Info[i].sum:= 0;

for k:=1 to 3 do begin

read(mark);

Info[i].sum:= Info[i].sum + mark;

end;

readln;

10) последняя команда readln пропускает все оставшиеся символы до новой строки (из этой мы прочитали все, что нужно)

11) вот полный цикл ввода данных, после его окончания все исходные данные будут записаны в первые N записей массива Info:

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;

Поиск трех худших данных:

12) теперь нужно придумать, как за один проход по массиву найти три худших результата;

13) как бы мы решили эту задачу, если бы нам нужно было просмотреть столбик чисел и найти три минимальных? можно сделать, например, так:

o на бумажке вести записи в три столбика, в первом записывать минимальное число, в втором – следующее по величине, в третьем – «третье минимальное»

o сначала пишем первое число в первый столбик, оно – минимальное, потому что других мы не еще видели; пусть это число 14:

минимум второе третье
     

o пусть следующее число – 12; оно меньше минимального, поэтому его нужно записывать в первый столбец, а «старое» минимальное число «переедет» во второй столбец

минимум второе третье
14    
     

o пусть дальше идет число 10 – теперь оно станет минимальным, его нужно записывать в первый столбец; при этом 12 «переедет» из первого столбца во второй, а 14 – из второго в третий

минимум второе третье
14    
12 14  
     

o пусть следующее число – 11; оно больше минимального, но меньше «второго», поэтому его нужно поставить во второй столбец; число 12 из второго столбца перемещается в третий, а число 14 из третьего столбца удаляется из кандидатов в «три минимальных»

минимум второе третье
14    
12 14  
  12 14
     

o просмотрев таким образом весь столбик чисел, за один проход (!) можно найти три минимальных элемента

o остается только переложить этот алгоритм на язык программирования

14) выделим в памяти три целых переменных: min1 (минимальный), min2 («второй минимальный»), min3 («третий минимальный»), в виде начальных значений запишем в каждую из них число, заведомо превышающее максимальную возможную сумму трех оценок, например, 20 (>5+5+5)

15) полный цикл поиска выглядит так:

min1:= 20; min2:= 20; min3:= 20;

for i:=1 to N do begin

if Info[i].sum < min1 then begin { новый min1 }

min3:= min2; min2:= min1;

min1:= Info[i].sum;

End

else if Info[i].sum < min2 then begin { новый min2 }

min3:= min2;

min2:= Info[i].sum;

End

else if Info[i].sum < min3 then { новый min3 }

min3:= Info[i].sum;

end;

16) обратим внимание на два момента: во-первых, когда переезжают два элемента, сначала нужно перемещать второй на место третьего, а потом – первый на место второго:

min3:= min2;

min2:= min1;

эти операторы нельзя менять местами, иначе «старое» значение min2 будет потеряно;

во-вторых, если проверять условие Info[i].sum < min2 нужно только тогда, когда очередная сумма не меньше, чем min1, поэтому каждый следующий условный оператор стоит в else -блоке предыдущего, то есть, выполняется только тогда, когда предыдущий не сработал

17) итак, мы нашли три минимальных результата, и остается вывести на экран фамилии и имена тех, у кого сумма баллов меньше или равна min3:

for i:=1 to N do

if Info[i].sum <= min3 then

writeln(Info[i].name);

18) на всякий случай приведем полную программу, она получилась довольно длинная

const LIM = 100;

var Info: array[1..LIM] of record

name: string;

sum: integer;

end;

i, k, N, mark, min1, min2, min3: 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;

{ поиск трех минимальных }

min1:= 20; min2:= 20; min3:= 20;

for i:=1 to N do begin

if Info[i].sum <min1 then begin

min3:= min2; min2:= min1;

min1:= Info[i].sum;

End

else if Info[i].sum <min2 then begin

min3:= min2;

min2:= Info[i].sum;

End

else if Info[i].sum <min3 then

min3:= Info[i].sum;

end;

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

for i:=1 to N do

if Info[i].sum <= min3 then

writeln(Info[i].name);

End.

19) эту задачу можно решить и без записей, используя два массива: массив символьных строк name и массив целых чисел sum, они объявляются так:

var name: array[1..MAX] of string;

sum: array[1..MAX] of integer;

после этого в приведенной программе нужно заменить везде Info[i].name на name и Info[i].sum на sum.

На что обратить внимание: · в исходных данных выделите то, что не нужно для решения задачи; при чтении эти части можно просто пропускать; · если нам не нужны фамилия и имя отдельно, можно хранить их вместе, в виде одной строки · если нас интересует только сумма оценок, не нужно хранить их в памяти по отдельности · если можно при решении задачи обойтись без вещественных чисел, сделав все вычисления только с целыми числами – нужно поступить именно так (иначе снимут баллы), поскольку операции с вещественными числами во многих случаях случаев выполняются неточно · алгоритм сложности (например, сортировку) нужно использовать только тогда, когда нет алгоритма сложности ; как правило, в задачах ЕГЭ такой алгоритм всегда можно (попытаться) найти; за неэффективный алгоритм при оценке решения будут сняты баллы

 

За что снимают баллы: · программа работает не для всех исходных данных, не обрабатывает некоторые частные случаи · неверно реализован алгоритм поиска минимального элемента, сортировки и т.п. · неэффективность алгоритма: o используется алгоритм, имеющий сложность , когда есть алгоритм сложности o используется несколько проходов по массиву, когда достаточно одного o лишний расход памяти (используются дополнительные массивы или размер массива определен неверно) o используются операции с вещественными числами, когда можно все решить в целых числах · переменная не описана или описана неверно · переменным не присвоены нужные начальные значения (например, не обнуляются счетчики) или присвоены неверные значения · нет вывода результата в конце программы · перепутаны знаки < и >, логические операции or и and · применяется недопустимая операция, например, div или mod для вещественных чисел · неверно расставлены операторные скобки begin-end · в цикле for используется вещественная переменная (Паскаль) · в цикле while или repeat не изменяется переменная цикла, из-за чего происходит зацикливание · синтаксические ошибки (знаки пунктуации – запятые, точки, точки с запятой; неверное написание ключевых слов); чтобы получить 4 балла, при абсолютно верном решении нужно сделать не более одной синтаксической ошибки; на 3 балла – до трех ошибок, на 2 балла – до пяти и на 1 балл – до семи ошибок

Задачи для тренировки [2]:

1) На вход программы подается 366 строк, которые содержат информацию о среднесуточной температуре всех дней 2008 года. Формат каждой из строк следующий: сначала записана дата в виде dd.mm (на запись номера дня и номера месяца в числовом формате отводится строго два символа, день от месяца отделен точкой), затем через пробел записано значение температуры — число со знаком плюс или минус, с точностью до 1 цифры после десятичной точки. Данная информация отсортирована по значению температуры, то есть хронологический порядок нарушен. Требуется написать программу на языке Паскаль или Бейсик, которая будет выводить на экран информацию о месяце (месяцах), среднемесячная температура у которого (которых) наименее отклоняется от среднегодовой. В первой строке вывести среднегодовую температуру. Найденные значения для каждого из месяцев следует выводить в отдельной строке в виде: номер месяца, значение среднемесячной температуры, отклонение от среднегодовой температуры.

 

2) На вход программы подается содержится текст на английском языке, заканчивающийся точкой (другие символы “.” в тексте отсутствуют). Требуется написать программу, которая будет определять и выводить на экран английскую букву, встречающуюся в этом тексте чаще всего, и количество там таких букв. Строчные и прописные буквы при этом считаются не различимыми. Если искомых букв несколько, то программа должна выводить на экран первую из них по алфавиту. Например, пусть файл содержит следующую запись:
It is not a simple task. Yes!
Чаще всего здесь встречаются буквы I, S и T (слово Yes в подсчете не учитывается, так как расположено после точки). Следовательно, в данном случае программа должна вывести два символа, разделенных пробелом: I 3

 

3) На вход программы подаются произвольные алфавитно-цифровые символы. Ввод этих символов заканчивается точкой. Требуется написать программу, которая будет печатать последовательность строчных английских букв ('a' 'b'... 'z') из входной последовательности и частот их повторения. Печать должна происходить в алфавитном порядке. Например, пусть на вход подаются следующие символы:

Fhb5kbfыshfm.

В этом случае программа должна вывести

b2

f3

h2

kl

ml

s1

 

4) На вход программы подаются фамилии и имена учеников. Известно, что общее количество учеников не превосходит 100. В первой строке вводится количество учеников, принимавших участие в соревнованиях, N. Далее следуют N строк, имеющих следующий формат:

<Фамилия> <Имя>

Здесь <Фамилия> – строка, состоящая не более чем из 20 символов; <Имя> – строка, состоящая не более чем из 15 символов. При этом <Фамилия> и <Имя> разделены одним пробелом. Примеры входных строк:

Иванова Мария

Петров Сергей

Требуется написать программу, которая формирует и печатает уникальный логин для каждого ученика по следующему правилу: если фамилия встречается первый раз, то логин – это данная фамилия, если фамилия встречается второй раз, то логин – это фамилия, в конец которой приписывается число 2 и т.д. Например, для входной последовательности

Иванова Мария

Петров Сергей

Бойцова Екатерина

Петров Иван

Иванова Наташа

будут сформированы следующие логины:

Иванова

Петров

Бойцова

Петров2

Иванова2

 

5) На городской олимпиаде по информатике участникам было предложено выполнить 3 задания, каждое из которых оценивалось по 25-балльной шкале. Известно, что общее количество участников первого тура олимпиады не превосходит 250 человек. На вход программы подаются сведения о результатах олимпиады. В первой строке вводится количество участников N. Далее следуют N строк, имеющих следующий формат:

<Фамилия> <Имя> <Баллы>

Здесь <Фамилия> – строка, состоящая не более чем из 20 символов; <Имя> – строка, состоящая не более чем из 15 символов; <Баллы> – строка, содержащая три целых числа, разделенных пробелом, соответствующих баллам, полученным участником за каждое задание первого тура. При этом <Фамилия> и <Имя>, <Имя> и <Баллы> разделены одним пробелом. Примеры входных строк:

Петрова Ольга 25 18 16

Калиниченко Иван 14 19 15

Напишите программу, которая будет выводить на экран фамилию и имя участника, набравшего максимальное количество баллов. Если среди остальных участников есть ученики, набравшие такое же количество баллов, то их фамилии и имена также следует вывести. При этом имена и фамилии можно выводить в произвольном порядке.

 

6) На вход программы подаются сведения о результатах соревнований по школьному многоборью. Многоборье состоит из соревнований по четырем видам спорта, участие в каждом из которых оценивается баллами от 0 до 10 (0 баллов получает ученик, не принимавший участия в соревнованиях по данному виду спорта). Победители определяются по наибольшей сумме набранных баллов. Известно, что общее количество участников соревнований не превосходит 100.

В первой строке вводится количество учеников, принимавших участие в соревнованиях, N. Далее следуют N строк, имеющих следующий формат:

<Фамилия> <Имя> <Баллы>

Здесь <Фамилия> – строка, состоящая не более чем из 20 символов; <Имя> – строка, состоящая не более чем из 15 символов; <Баллы> - строка, содержащая четыре целых числа, разделенных пробелом, соответствующих баллам, полученным на соревнованиях по каждому из четырех видов спорта. При этом <Фамилия> и <Имя>, <Имя> и <Баллы> разделены одним пробелом. Примеры входных строк:

Иванова Мария 5 8 6 3

Петров Сергей 9 9 5 7

Напишите программу, которая будет выводить на экран фамилии и имена трех лучших участников многоборья. Если среди остальных участников есть ученики, набравшие то же количество баллов, что и один из трех лучших, то их фамилии и имена также следует вывести. При этом имена и фамилии можно выводить в произвольном порядке.

 

7) В некотором вузе абитуриенты проходят предварительное тестирование, по результатам которого могут быть допущены к сдаче вступительных экзаменов в первом потоке. Тестирование проводится по двум предметам, по каждому предмету абитуриент может набрать от 0 до 100 баллов. При этом к сдаче экзаменов в первом потоке допускаются абитуриенты, набравшие по результатам тестирования не менее 30 баллов по каждому из двух предметов. На вход программы подаются сведения о результатах предварительного тестирования. Известно, что общее количество участников тестирования не превосходит 500.
В первой строке вводится количество абитуриентов, принимавших участие в тестировании, N. Далее следуют N строк, имеющих следующий формат:

<Фамилия> <Имя> <Баллы>

Здесь <Фамилия> – строка, состоящая не более чем из 20 символов; <Имя> – строка, состоящая не более чем из 15 символов; <Баллы> – строка, содержащая два целых числа, разделенных пробелом, соответствующих баллам, полученным на тестировании по каждому из двух предметов. При этом <Фамилия> и <Имя>, <Имя> и <Баллы> разделены одним пробелом. Примеры входных строк:

Ветров Роман 68 59

Анисимова Екатерина 64 88

Напишите программу, которая будет выводить на экран фамилии и имена абитуриентов, потерпевших неудачу, то есть не допущенных к сдаче экзаменов в первом потоке. При этом фамилии должны выводиться в алфавитном порядке.

 

8) На вход программе подаются сведения о телефонах всех сотрудников некоторого учреждения. В первой строке сообщается количество сотрудников N, каждая из следующих N строк имеет следующий формат:

<Фамилия> <Инициалы> <телефон>

где <Фамилия> – строка, состоящая не более чем из 20 символов, <Инициалы> - строка, состоящая не более чем из 4-х символов (буква, точка, буква, точка), <телефон> – семизначный номер, 3-я и 4, я, а также 5-я и 6-я цифры которого разделены символом «–». <Фамилия> и <Инициалы>, а также <Инициалы> и <телефон> разделены одним пробелом. Пример входной строки:

Иванов П.С. 555-66-77

Сотрудники одного подразделения имеют один и тот же номер телефона. Номера телефонов в учреждении отличаются только двумя последними цифрами. Требуется написать как можно более эффективную программу, которая будет выводить на экран информацию, сколько в среднем сотрудников работает в одном подразделении данного учреждения.

 

9) На вход программе сначала подается число участников олимпиады N. В каждой из следующих N строк находится результат одного из участников олимпиады в следующем формате:

<Фамилия> <Имя> <класс> <баллы>

где <Фамилия> – символьная строка (не более 20 символов), <Имя> – символьная строка (не более 15 символов), <класс> – число от 7 до 11, <баллы> – целое число набранных участником баллов. <Фамилия> и <Имя>, <Имя> и <класс>, а также <класс> и <баллы> разделены одним пробелом. Пример входной строки:

Семенов Егор 11 225

Победителем олимпиады становится участник, набравший наибольшее количество баллов, при условии, что он набрал более 200 баллов. Если такое количество баллов набрали несколько участников, то все они признаются победителями при выполнении условия, что их доля не превышает 20% от общего числа участников.

Победителем олимпиады не признается никто, если нет участников, набравших больше 200 баллов, или больше 20% от общего числа участников набрали одинаковый наибольший балл.

Напишите эффективную по времени работы и по используемой памяти программу, которая будет определять фамилию и имя лучшего участника, не ставшего победителем олимпиады. Если таких участников несколько, т.е. если следующий за баллом победителей один и тот же балл набрали несколько человек, или, если победителей нет, а лучших участников несколько (в этом случае именно они являются искомыми), то выдается только количество искомых участников. Гарантируется, что искомые участники (участник) имеются.

Программа должна выводить через пробел фамилию и имя искомого участника или их количество. Пример выходных данных (один искомый участник):

Семенов Егор

Второй вариант выходных данных (несколько искомых участников):

10) В молочных магазинах города Х продается сметана с жирностью 15, 20 и 25 процентов. В городе X был проведен мониторинг цен на сметану. Напишите эффективную по времени работы и по используемой памяти программу, которая будет определять для каждого вида сметаны, сколько магазинов продают ее дешевле всего. На вход программе сначала подается число магазинов N. В каждой из следующих N строк находится информация в следующем формате:

<Фирма> <Улица> <Жирность> <Цена>

где <Фирма> – строка, состоящая не более, чем из 20 символов без пробелов, <Улица> – строка, состоящая не более, чем из 20 символов без пробелов, <Жирность> – одно из чисел – 15, 20 или 25, <Цена> – целое число в диапазоне от 2000 до 5000, обозначающее стоимость одного литра сметаны в копейках. <Фирма> и <Улица>, <Улица> и <Жирность>, а также <Жирность> и <Цена> разделены ровно одним пробелом. Пример входной строки:

Поделиться:





Воспользуйтесь поиском по сайту:



©2015 - 2024 megalektsii.ru Все авторские права принадлежат авторам лекционных материалов. Обратная связь с нами...