Министерство образования и науки Российской Федерации

Федеральное государственное автономное образовательное учреждение
высшего профессионального образования
«ЮЖНЫЙ ФЕДЕРАЛЬНЫЙ УНИВЕРСИТЕТ»

А. В. Абрамян, М. Э. Абрамян

1300 задач по программированию
и их использование на практических занятиях

Электронное учебное пособие

Ростов-на-Дону 2012

Публикуется по решению учебно-методической комиссии
факультета математики, механики и компьютерных наук ЮФУ
от 3 мая 2012 г. (протокол № 8)

Рецензенты:
к. ф.-м. н., доцент С. С. Михалкович,
ст. преп. Л. А. Мачулина

Аннотация

Электронное пособие состоит из двух разделов. Первый раздел содержит формулировки 1300 учебных задач. Задачи разбиты на 21 группу, каждая из которых посвящена определенной теме базового курса программирования. Приводятся задачи начального уровня (на скалярные типы данных, управляющие операторы, процедуры и функции), задачи на обработку сложных типов данных (одномерные и двумерные массивы, символьные строки, двоичные и текстовые файлы), задачи на рекурсивные алгоритмы и динамические структуры (стеки, очереди, списки, деревья), а также задачи, связанные с ЕГЭ по информатике. Во втором разделе дается общий обзор каждой группы задач, рассматриваются особенности заданий, входящих в эти группы, и даются методические рекомендации по организации практических занятий, посвященных соответствующей теме. Все упоминания конкретных задач во втором разделе снабжены гиперссылками, позволяющими сразу перейти к формулировке задачи, приведенной в первом разделе пособия.

Для преподавателей программирования, старшеклассников и студентов.

Авторы: А. В. Абрамян, М. Э. Абрамян.


Предисловие

[Перейти к титульному листу] [Перейти к началу раздела «Группы заданий»] [Перейти к началу раздела «Указания»] [Перейти к списку литературы]

Настоящее электронное пособие представляет собой дополненный вариант ранее опубликованных пособий [2, 3].

В первый раздел пособия включены формулировки 1300 учебных задач, охватывающих все темы базового курса программирования: от скалярных типов и управляющих операторов до сложных типов данных, рекурсивных алгоритмов и динамических структур. Задания составлены с учетом опыта проведения практических занятий по программированию на факультете математики, механики и компьютерных наук Южного федерального университета, а также в Компьютерной школе при мехмате ЮФУ. При разработке заданий были использованы материалы пособий [11–25].

По сравнению со сборником [3] количество заданий увеличилось почти на треть за счет добавления 300 новых задач. Из них 100 задач посвящены алгоритмам обработки деревьев (группа Tree и ее вариант для языков платформы .NET), а 200 задач связаны с ЕГЭ по информатике (группы ExamBegin и ExamTaskC). Задачи, входящие в группу ExamBegin, могут рассматриваться как сводный набор заданий для повторения ранее изученных базовых алгоритмов (вплоть до алгоритмов обработки массивов и строк), а задачи из группы ExamTaskC посвящены обработке сложных структур данных, и в этом качестве также могут использоваться при итоговом повторении.

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

Формулировки заданий не привязаны к определенному языку программирования, поэтому задания могут использоваться для большинства языков, применяемых в настоящее время при обучении программированию: Pascal, Visual Basic, C# и Visual Basic.NET, C++, Python и т. д.

Все задачи, приведенные в пособии, входят в состав базового набора заданий электронного задачника Programming Taskbook, разработанного на факультете математики, механики и компьютерных наук ЮФУ (автор доц. М. Э. Абрамян). Задачник Programming Taskbook предоставляет учащимся следующие возможности:

  • задания могут выполняться на любом языке и в любой программной среде, поддерживаемой задачником (языки Pascal, Visual Basic, C++, C#, Visual Basic .NET, Python; программные среды PascalABC.NET, Free Pascal Lazarus, Turbo Delphi, Microsoft Visual Studio .NET, IDLE for Python и др.);
  • при выполнении заданий программа получает от задачника набор исходных тестовых данных для обработки (данные генерируются с использованием датчика случайных чисел);
  • результаты, полученные программой, передаются задачнику для проверки (сравнения с образцом правильных данных);
  • полученные результаты, наряду с исходными данными и примером правильного решения, отображаются в наглядном виде в окне задачника;
  • задание считается выполненным (и информация об этом заносится в специальный файл результатов), если программа учащегося успешно обработает подряд несколько наборов исходных данных, предложенных задачником.

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

Рассматриваемый в пособии базовый набор может быть расширен путем разработки новых групп заданий. Для этого предназначен конструктор учебных заданий PT4TaskMaker [6], входящий в состав программного комплекса Teacher Pack. Программный комплекс Teacher Pack предназначен для преподавателя программирования и является дополнением к электронному задачнику Programming Taskbook. Помимо конструктора учебных заданий комплекс включает конструктор вариантов PTVarMaker, упрощающий процесс разработки вариантов индивидуальных заданий, и контрольный центр, предназначенный для автоматизации действий преподавателя при подготовке и проведении групповых лабораторных занятий с применением электронного задачника Programming Taskbook [4].

Дополнительная информация, связанная с электронным задачником Programming Taskbook, содержится на его сайте http://ptaskbook.com/. С этого же сайта можно загрузить как сам задачник, так и комплекс Teacher Pack, а также другие дополнительные компоненты задачника.

Ниже приводится список всех пунктов настоящего пособия.

  • Группы заданий
    • Begin
    • Integer
    • Boolean
    • If
    • Case
    • For
    • While
    • Proc
    • Series
    • Minmax
    • Array
    • Matrix
    • String
    • File
    • Text
    • Param
    • Recur
    • Dynamic
    • Dynamic .NET
    • Tree
    • Tree .NET
    • ExamBegin
    • ExamTaskC
  • Указания
    • Begin, Integer, Boolean
    • If, Case, For, While
    • Proc
    • Series, Minmax
    • Array
    • Matrix
    • String
    • File
    • Text
    • Param
    • Recur
    • Dynamic
    • Tree
    • ExamBegin, ExamTaskC
  • Литература


Группы заданий

[Перейти к предисловию] [Перейти к началу раздела «Указания»] [Перейти к списку литературы]

В данном разделе приводятся формулировки учебных заданий по программированию. Задания разбиты на 21 группу, каждая из которых посвящена определенной теме базового курса программирования. Ниже приводится список групп; в скобках указывается количество заданий, входящих в каждую группу.

  • Begin — ввод и вывод данных, оператор присваивания (40),
  • Integer — целые числа (30),
  • Boolean — логические выражения (40),
  • If — условный оператор (30),
  • Case — оператор выбора (20),
  • For — цикл с параметром (40),
  • While — цикл с условием (30),
  • Proc — процедуры и функции (60),
  • Series — последовательности (40),
  • Minmax — минимумы и максимумы (30),
  • Array — одномерные массивы (140),
  • Matrix — двумерные массивы (100),
  • String — символы и строки (70),
  • File — двоичные файлы (90),
  • Text — текстовые файлы (60),
  • Param — составные типы данных в процедурах и функциях (70),
  • Recur — рекурсия (30),
  • Dynamic и Dynamic (.NET) — динамические структуры данных (80),
  • Tree и Tree (.NET) — деревья (100),
  • ExamBegin — ЕГЭ по информатике: базовые алгоритмы (100),
  • ExamTaskC — ЕГЭ по информатике: задачи повышенной сложности (100).

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

Если о типе исходных или результирующих числовых данных в задании ничего не сказано, то предполагаются вещественные данные. Исключение составляют группы заданий Dynamic и Tree, в которых все числовые данные считаются целыми, и в формулировках заданий это особо не оговаривается.

При обработке наборов вещественных чисел следует предполагать, что все элементы набора являются различными (таким образом, любой набор вещественных чисел содержит единственный минимальный и единственный максимальный элемент). В наборах целых чисел могут присутствовать одинаковые элементы; в частности, наборы целых чисел могут содержать несколько минимальных и максимальных элементов. Аналогичные предположения справедливы для числовых массивов, а также для файлов, содержащих числовые данные.

Если в задании не указан максимальный размер исходных массивов, то его можно считать равным 10 для одномерных и 10 × 10 для двумерных массивов.

При описании элементов одномерных и двумерных массивов используется понятие порядкового номера элемента, причем начальный элемент массива A размера N всегда имеет порядковый номер 1 и обозначается в формулировках заданий как A1, а конечный элемент этого же массива имеет порядковый номер N и обозначается как AN. Аналогично, начальный элемент двумерного массива B обозначается как B1,1. Кроме того, понятие порядкового номера применяется к строкам и столбцам двумерных массивов (матриц): начальная строка и начальный столбец матрицы размера M × N имеют порядковый номер 1, конечная строка — номер M, а конечный столбец — номер N. Подобный подход не зависит от выбора языка программирования и соответствует традиционно используемой в математике нумерации элементов векторов и матриц.

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

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

Если в используемом языке программирования отсутствует понятие «процедура», то под процедурой в формулировках заданий групп Proc, Param и Dynamic надо понимать функцию, не имеющую возвращаемого значения.

Формулировки заданий групп Dynamic и Tree приводятся в двух вариантах: первый вариант (см. разделы «Dynamic» и «Tree») ориентирован на применение указателей и предназначен для языков Pascal и C++, второй вариант (см. разделы «Dynamic .NET» и «Tree .NET») ориентирован на использование объектной модели платформы .NET и предназначен для языков C# и Visual Basic .NET.

Все задачи, приведенные в настоящем разделе, входят в состав электронного задачника по программированию Programming Taskbook (http://ptaskbook.com/).

В реализации задачника для системы PascalABC.NET доступны оба варианта групп Dynamic и Tree (для вариантов групп Dynamic и Tree, ориентированных на использование объектной модели .NET, используются названия ObjDyn и ObjTree соответственно). В реализации задачника для языка Visual Basic группы Dynamic и Tree отсутствуют.

Группы ExamBegin и ExamTaskC, связанные с ЕГЭ по информатике, входят в электронный задачник Programming Taskbook, начиная с версии 4.10 задачника, и реализованы в нем только для языков Pascal и C++.


Группы заданий

Ввод и вывод данных, оператор присваивания: группа Begin

[Перейти к указаниям] [Перейти к началу раздела «Группы заданий»] [Перейти к началу раздела «Указания»]

Все входные и выходные данные в заданиях этой группы являются вещественными числами.

Begin1. Дана сторона квадрата a. Найти его периметр P = 4·a.

Begin2. Дана сторона квадрата a. Найти его площадь S = a2.

Begin3. Даны стороны прямоугольника a и b. Найти его площадь S = a·b и периметр P = 2·(a + b).

Begin4. Дан диаметр окружности d. Найти ее длину L = π·d. В качестве значения π использовать 3.14.

Begin5. Дана длина ребра куба a. Найти объем куба V = a3 и площадь его поверхности S = 6·a2.

Begin6. Даны длины ребер a, b, c прямоугольного параллелепипеда. Найти его объем V = a·b·c и площадь поверхности S = 2·(a·b + b·c + a·c).

Begin7. Найти длину окружности L и площадь круга S заданного радиуса R:

L = 2·π·R, S = π·R2.

В качестве значения π использовать 3.14.

Begin8. Даны два числа a и b. Найти их среднее арифметическое: (a + b)/2.

Begin9. Даны два неотрицательных числа a и b. Найти их среднее геометрическое, т. е. квадратный корень из их произведения: (a·b)1/2.

Begin10. Даны два ненулевых числа. Найти сумму, разность, произведение и частное их квадратов.

Begin11. Даны два ненулевых числа. Найти сумму, разность, произведение и частное их модулей.

Begin12. Даны катеты прямоугольного треугольника a и b. Найти его гипотенузу c и периметр P:

c = (a2 + b2)1/2, P = a + b + c.

Begin13. Даны два круга с общим центром и радиусами R1 и R2 (R1 > R2). Найти площади этих кругов S1 и S2, а также площадь S3 кольца, внешний радиус которого равен R1, а внутренний радиус равен R2:

S1 = π·(R1)2, S2 = π·(R2)2, S3 = S1 − S2.

В качестве значения π использовать 3.14.

Begin14. Дана длина L окружности. Найти ее радиус R и площадь S круга, ограниченного этой окружностью, учитывая, что L = 2·π·R, S = π·R2. В качестве значения π использовать 3.14.

Begin15. Дана площадь S круга. Найти его диаметр D и длину L окружности, ограничивающей этот круг, учитывая, что L = π·D, S = π·D2/4. В качестве значения π использовать 3.14.

Begin16. Найти расстояние между двумя точками с заданными координатами x1 и x2 на числовой оси: |x2 − x1|.

Begin17. Даны три точки A, B, C на числовой оси. Найти длины отрезков AC и BC и их сумму.

Begin18. Даны три точки A, B, C на числовой оси. Точка C расположена между точками A и B. Найти произведение длин отрезков AC и BC.

Begin19. Даны координаты двух противоположных вершин прямоугольника: (x1, y1), (x2, y2). Стороны прямоугольника параллельны осям координат. Найти периметр и площадь данного прямоугольника.

Begin20. Найти расстояние между двумя точками с заданными координатами (x1, y1) и (x2, y2) на плоскости. Расстояние вычисляется по формуле

((x2 − x1)2 + (y2 − y1)2)1/2.

Begin21. Даны координаты трех вершин треугольника: (x1, y1), (x2, y2), (x3, y3). Найти его периметр и площадь, используя формулу для расстояния между двумя точками на плоскости (см. задание Begin20). Для нахождения площади треугольника со сторонами a, b, c использовать формулу Герона:

S = (p·(p − a)·(p − b)·(p − c))1/2,

где p = (a + b + c)/2 — полупериметр.

Begin22. Поменять местами содержимое переменных A и B и вывести новые значения A и B.

Begin23. Даны переменные A, B, C. Изменить их значения, переместив содержимое A в B, B — в C, C — в A, и вывести новые значения переменных A, B, C.

Begin24. Даны переменные A, B, C. Изменить их значения, переместив содержимое A в C, C — в B, B — в A, и вывести новые значения переменных A, B, C.

Begin25. Найти значение функции y = 3x6 − 6x2 − 7 при данном значении x.

Begin26. Найти значение функции y = 4(x−3)6 − 7(x−3)3 + 2 при данном значении x.

Begin27. Дано число A. Вычислить A8, используя вспомогательную переменную и три операции умножения. Для этого последовательно находить A2, A4, A8. Вывести все найденные степени числа A.

Begin28. Дано число A. Вычислить A15, используя две вспомогательные переменные и пять операций умножения. Для этого последовательно находить A2, A3, A5, A10, A15. Вывести все найденные степени числа A.

Begin29. Дано значение угла α в градусах (0 ≤ α < 360). Определить значение этого же угла в радианах, учитывая, что 180° = π радианов. В качестве значения π использовать 3.14.

Begin30. Дано значение угла α в радианах (0 ≤ α < 2·π). Определить значение этого же угла в градусах, учитывая, что 180° = π радианов. В качестве значения π использовать 3.14.

Begin31. Дано значение температуры T в градусах Фаренгейта. Определить значение этой же температуры в градусах Цельсия. Температура по Цельсию TC и температура по Фаренгейту TF связаны следующим соотношением:

TC = (TF − 32)·5/9.

Begin32. Дано значение температуры T в градусах Цельсия. Определить значение этой же температуры в градусах Фаренгейта. Температура по Цельсию TC и температура по Фаренгейту TF связаны следующим соотношением:

TC = (TF − 32)·5/9.

Begin33. Известно, что X кг конфет стоит A рублей. Определить, сколько стоит 1 кг и Y кг этих же конфет.

Begin34. Известно, что X кг шоколадных конфет стоит A рублей, а Y кг ирисок стоит B рублей. Определить, сколько стоит 1 кг шоколадных конфет, 1 кг ирисок, а также во сколько раз шоколадные конфеты дороже ирисок.

Begin35. Скорость лодки в стоячей воде V км/ч, скорость течения реки U км/ч (U < V). Время движения лодки по озеру T1 ч, а по реке (против течения) — T2 ч. Определить путь S, пройденный лодкой (путь = время · скорость). Учесть, что при движении против течения скорость лодки уменьшается на величину скорости течения.

Begin36. Скорость первого автомобиля V1 км/ч, второго — V2 км/ч, расстояние между ними S км. Определить расстояние между ними через T часов, если автомобили удаляются друг от друга, двигаясь в противоположных направлениях. Данное расстояние равно сумме начального расстояния и общего пути, проделанного автомобилями; общий путь = время · суммарная скорость.

Begin37. Скорость первого автомобиля V1 км/ч, второго — V2 км/ч, расстояние между ними S км. Определить расстояние между ними через T часов, если автомобили первоначально движутся навстречу друг другу. Данное расстояние равно модулю разности начального расстояния и общего пути, проделанного автомобилями; общий путь = время · суммарная скорость.

Begin38. Решить линейное уравнение A·x + B = 0, заданное своими коэффициентами A и B (коэффициент A не равен 0).

Begin39. Найти корни квадратного уравнения A·x2 + B·x + C = 0, заданного своими коэффициентами A, B, C (коэффициент A не равен 0), если известно, что дискриминант уравнения положителен. Вывести вначале меньший, а затем больший из найденных корней. Корни квадратного уравнения находятся по формуле

x1, 2 = (−B ± (D)1/2)/(2·A),

где D — дискриминант, равный B2 − 4·A·C.

Begin40. Найти решение системы линейных уравнений вида

A1·x + B1·y = C1,
A2·x + B2·y = C2,

заданной своими коэффициентами A1, B1, C1, A2, B2, C2, если известно, что данная система имеет единственное решение. Воспользоваться формулами

x = (C1·B2 − C2·B1)/D, y = (A1·C2 − A2·C1)/D,
где D = A1·B2 − A2·B1.


Группы заданий

Целые числа: группа Integer

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

Integer1. Дано расстояние L в сантиметрах. Используя операцию деления нацело, найти количество полных метров в нем (1 метр = 100 см).

Integer2. Дана масса M в килограммах. Используя операцию деления нацело, найти количество полных тонн в ней (1 тонна = 1000 кг).

Integer3. Дан размер файла в байтах. Используя операцию деления нацело, найти количество полных килобайтов, которые занимает данный файл (1 килобайт = 1024 байта).

Integer4. Даны целые положительные числа A и B (A > B). На отрезке длины A размещено максимально возможное количество отрезков длины B (без наложений). Используя операцию деления нацело, найти количество отрезков B, размещенных на отрезке A.

Integer5. Даны целые положительные числа A и B (A > B). На отрезке длины A размещено максимально возможное количество отрезков длины B (без наложений). Используя операцию взятия остатка от деления нацело, найти длину незанятой части отрезка A.

Integer6. Дано двузначное число. Вывести вначале его левую цифру (десятки), а затем — его правую цифру (единицы). Для нахождения десятков использовать операцию деления нацело, для нахождения единиц — операцию взятия остатка от деления.

Integer7. Дано двузначное число. Найти сумму и произведение его цифр.

Integer8. Дано двузначное число. Вывести число, полученное при перестановке цифр исходного числа.

Integer9. Дано трехзначное число. Используя одну операцию деления нацело, вывести первую цифру данного числа (сотни).

Integer10. Дано трехзначное число. Вывести вначале его последнюю цифру (единицы), а затем — его среднюю цифру (десятки).

Integer11. Дано трехзначное число. Найти сумму и произведение его цифр.

Integer12. Дано трехзначное число. Вывести число, полученное при прочтении исходного числа справа налево.

Integer13. Дано трехзначное число. В нем зачеркнули первую слева цифру и приписали ее справа. Вывести полученное число.

Integer14. Дано трехзначное число. В нем зачеркнули первую справа цифру и приписали ее слева. Вывести полученное число.

Integer15. Дано трехзначное число. Вывести число, полученное при перестановке цифр сотен и десятков исходного числа (например, 123 перейдет в 213).

Integer16. Дано трехзначное число. Вывести число, полученное при перестановке цифр десятков и единиц исходного числа (например, 123 перейдет в 132).

Integer17. Дано целое число, большее 999. Используя одну операцию деления нацело и одну операцию взятия остатка от деления, найти цифру, соответствующую разряду сотен в записи этого числа.

Integer18. Дано целое число, большее 999. Используя одну операцию деления нацело и одну операцию взятия остатка от деления, найти цифру, соответствующую разряду тысяч в записи этого числа.

Integer19. С начала суток прошло N секунд (N — целое). Найти количество полных минут, прошедших с начала суток.

Integer20. С начала суток прошло N секунд (N — целое). Найти количество полных часов, прошедших с начала суток.

Integer21. С начала суток прошло N секунд (N — целое). Найти количество секунд, прошедших с начала последней минуты.

Integer22. С начала суток прошло N секунд (N — целое). Найти количество секунд, прошедших с начала последнего часа.

Integer23. С начала суток прошло N секунд (N — целое). Найти количество полных минут, прошедших с начала последнего часа.

Integer24. Дни недели пронумерованы следующим образом: 0 — воскресенье, 1 — понедельник, 2 — вторник, …, 6 — суббота. Дано целое число K, лежащее в диапазоне 1–365. Определить номер дня недели для K-го дня года, если известно, что в этом году 1 января было понедельником.

Integer25. Дни недели пронумерованы следующим образом: 0 — воскресенье, 1 — понедельник, 2 — вторник, …, 6 — суббота. Дано целое число K, лежащее в диапазоне 1–365. Определить номер дня недели для K-го дня года, если известно, что в этом году 1 января было четвергом.

Integer26. Дни недели пронумерованы следующим образом: 1 — понедельник, 2 — вторник, …, 6 — суббота, 7 — воскресенье. Дано целое число K, лежащее в диапазоне 1–365. Определить номер дня недели для K-го дня года, если известно, что в этом году 1 января было вторником.

Integer27. Дни недели пронумерованы следующим образом: 1 — понедельник, 2 — вторник, …, 6 — суббота, 7 — воскресенье. Дано целое число K, лежащее в диапазоне 1–365. Определить номер дня недели для K-го дня года, если известно, что в этом году 1 января было субботой.

Integer28. Дни недели пронумерованы следующим образом: 1 — понедельник, 2 — вторник, …, 6 — суббота, 7 — воскресенье. Дано целое число K, лежащее в диапазоне 1–365, и целое число N, лежащее в диапазоне 1–7. Определить номер дня недели для K-го дня года, если известно, что в этом году 1 января было днем недели с номером N.

Integer29. Даны целые положительные числа A, B, C. На прямоугольнике размера A × B размещено максимально возможное количество квадратов со стороной C (без наложений). Найти количество квадратов, размещенных на прямоугольнике, а также площадь незанятой части прямоугольника.

Integer30. Дан номер некоторого года (целое положительное число). Определить соответствующий ему номер столетия, учитывая, что, к примеру, началом 20 столетия был 1901 год.


Группы заданий

Логические выражения: группа Boolean

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

Boolean1. Дано целое число A. Проверить истинность высказывания: «Число A является положительным».

Boolean2. Дано целое число A. Проверить истинность высказывания: «Число A является нечетным».

Boolean3. Дано целое число A. Проверить истинность высказывания: «Число A является четным».

Boolean4. Даны два целых числа: A, B. Проверить истинность высказывания: «Справедливы неравенства A > 2 и B ≤ 3».

Boolean5. Даны два целых числа: A, B. Проверить истинность высказывания: «Справедливы неравенства A ≥ 0 или B < −2».

Boolean6. Даны три целых числа: A, B, C. Проверить истинность высказывания: «Справедливо двойное неравенство A < B < C».

Boolean7. Даны три целых числа: A, B, C. Проверить истинность высказывания: «Число B находится между числами A и C».

Boolean8. Даны два целых числа: A, B. Проверить истинность высказывания: «Каждое из чисел A и B нечетное».

Boolean9. Даны два целых числа: A, B. Проверить истинность высказывания: «Хотя бы одно из чисел A и B нечетное».

Boolean10. Даны два целых числа: A, B. Проверить истинность высказывания: «Ровно одно из чисел A и B нечетное».

Boolean11. Даны два целых числа: A, B. Проверить истинность высказывания: «Числа A и B имеют одинаковую четность».

Boolean12. Даны три целых числа: A, B, C. Проверить истинность высказывания: «Каждое из чисел A, B, C положительное».

Boolean13. Даны три целых числа: A, B, C. Проверить истинность высказывания: «Хотя бы одно из чисел A, B, C положительное».

Boolean14. Даны три целых числа: A, B, C. Проверить истинность высказывания: «Ровно одно из чисел A, B, C положительное».

Boolean15. Даны три целых числа: A, B, C. Проверить истинность высказывания: «Ровно два из чисел A, B, C являются положительными».

Boolean16. Дано целое положительное число. Проверить истинность высказывания: «Данное число является четным двузначным».

Boolean17. Дано целое положительное число. Проверить истинность высказывания: «Данное число является нечетным трехзначным».

Boolean18. Проверить истинность высказывания: «Среди трех данных целых чисел есть хотя бы одна пара совпадающих».

Boolean19. Проверить истинность высказывания: «Среди трех данных целых чисел есть хотя бы одна пара взаимно противоположных».

Boolean20. Дано трехзначное число. Проверить истинность высказывания: «Все цифры данного числа различны».

Boolean21. Дано трехзначное число. Проверить истинность высказывания: «Цифры данного числа образуют возрастающую последовательность».

Boolean22. Дано трехзначное число. Проверить истинность высказывания: «Цифры данного числа образуют возрастающую или убывающую последовательность».

Boolean23. Дано четырехзначное число. Проверить истинность высказывания: «Данное число читается одинаково слева направо и справа налево».

Boolean24. Даны числа A, B, C (число A не равно 0). Рассмотрев дискриминант D = B2 − 4·A·C, проверить истинность высказывания: «Квадратное уравнение A·x2 + B·x + C = 0 имеет вещественные корни».

Boolean25. Даны числа x, y. Проверить истинность высказывания: «Точка с координатами (x, y) лежит во второй координатной четверти».

Boolean26. Даны числа x, y. Проверить истинность высказывания: «Точка с координатами (x, y) лежит в четвертой координатной четверти».

Boolean27. Даны числа x, y. Проверить истинность высказывания: «Точка с координатами (x, y) лежит во второй или третьей координатной четверти».

Boolean28. Даны числа x, y. Проверить истинность высказывания: «Точка с координатами (x, y) лежит в первой или третьей координатной четверти».

Boolean29. Даны числа x, y, x1, y1, x2, y2. Проверить истинность высказывания: «Точка с координатами (x, y) лежит внутри прямоугольника, левая верхняя вершина которого имеет координаты (x1, y1), правая нижняя — (x2, y2), а стороны параллельны координатным осям».

Boolean30. Даны целые числа a, b, c, являющиеся сторонами некоторого треугольника. Проверить истинность высказывания: «Треугольник со сторонами a, b, c является равносторонним».

Boolean31. Даны целые числа a, b, c, являющиеся сторонами некоторого треугольника. Проверить истинность высказывания: «Треугольник со сторонами a, b, c является равнобедренным».

Boolean32. Даны целые числа a, b, c, являющиеся сторонами некоторого треугольника. Проверить истинность высказывания: «Треугольник со сторонами a, b, c является прямоугольным».

Boolean33. Даны целые числа a, b, c. Проверить истинность высказывания: «Существует треугольник со сторонами a, b, c».

Boolean34. Даны координаты поля шахматной доски x, y (целые числа, лежащие в диапазоне 1–8). Учитывая, что левое нижнее поле доски (1, 1) является черным, проверить истинность высказывания: «Данное поле является белым».

Boolean35. Даны координаты двух различных полей шахматной доски x1, y1, x2, y2 (целые числа, лежащие в диапазоне 1–8). Проверить истинность высказывания: «Данные поля имеют одинаковый цвет».

Boolean36. Даны координаты двух различных полей шахматной доски x1, y1, x2, y2 (целые числа, лежащие в диапазоне 1–8). Проверить истинность высказывания: «Ладья за один ход может перейти с одного поля на другое».

Boolean37. Даны координаты двух различных полей шахматной доски x1, y1, x2, y2 (целые числа, лежащие в диапазоне 1–8). Проверить истинность высказывания: «Король за один ход может перейти с одного поля на другое».

Boolean38. Даны координаты двух различных полей шахматной доски x1, y1, x2, y2 (целые числа, лежащие в диапазоне 1–8). Проверить истинность высказывания: «Слон за один ход может перейти с одного поля на другое».

Boolean39. Даны координаты двух различных полей шахматной доски x1, y1, x2, y2 (целые числа, лежащие в диапазоне 1–8). Проверить истинность высказывания: «Ферзь за один ход может перейти с одного поля на другое».

Boolean40. Даны координаты двух различных полей шахматной доски x1, y1, x2, y2 (целые числа, лежащие в диапазоне 1–8). Проверить истинность высказывания: «Конь за один ход может перейти с одного поля на другое».


Группы заданий

Условный оператор: группа If

If1. Дано целое число. Если оно является положительным, то прибавить к нему 1; в противном случае не изменять его. Вывести полученное число.

If2. Дано целое число. Если оно является положительным, то прибавить к нему 1; в противном случае вычесть из него 2. Вывести полученное число.

If3. Дано целое число. Если оно является положительным, то прибавить к нему 1; если отрицательным, то вычесть из него 2; если нулевым, то заменить его на 10. Вывести полученное число.

If4. Даны три целых числа. Найти количество положительных чисел в исходном наборе.

If5. Даны три целых числа. Найти количество положительных и количество отрицательных чисел в исходном наборе.

If6. Даны два числа. Вывести большее из них.

If7. Даны два числа. Вывести порядковый номер меньшего из них.

If8. Даны два числа. Вывести вначале большее, а затем меньшее из них.

If9. Даны две переменные вещественного типа: A, B. Перераспределить значения данных переменных так, чтобы в A оказалось меньшее из значений, а в B — большее. Вывести новые значения переменных A и B.

If10. Даны две переменные целого типа: A и B. Если их значения не равны, то присвоить каждой переменной сумму этих значений, а если равны, то присвоить переменным нулевые значения. Вывести новые значения переменных A и B.

If11. Даны две переменные целого типа: A и B. Если их значения не равны, то присвоить каждой переменной большее из этих значений, а если равны, то присвоить переменным нулевые значения. Вывести новые значения переменных A и B.

If12. Даны три числа. Найти наименьшее из них.

If13. Даны три числа. Найти среднее из них (т. е. число, расположенное между наименьшим и наибольшим).

If14. Даны три числа. Вывести вначале наименьшее, а затем наибольшее из данных чисел.

If15. Даны три числа. Найти сумму двух наибольших из них.

If16. Даны три переменные вещественного типа: A, B, C. Если их значения упорядочены по возрастанию, то удвоить их; в противном случае заменить значение каждой переменной на противоположное. Вывести новые значения переменных A, B, C.

If17. Даны три переменные вещественного типа: A, B, C. Если их значения упорядочены по возрастанию или убыванию, то удвоить их; в противном случае заменить значение каждой переменной на противоположное. Вывести новые значения переменных A, B, C.

If18. Даны три целых числа, одно из которых отлично от двух других, равных между собой. Определить порядковый номер числа, отличного от остальных.

If19. Даны четыре целых числа, одно из которых отлично от трех других, равных между собой. Определить порядковый номер числа, отличного от остальных.

If20. На числовой оси расположены три точки: A, B, C. Определить, какая из двух последних точек (B или C) расположена ближе к A, и вывести эту точку и ее расстояние от точки A.

If21. Даны целочисленные координаты точки на плоскости. Если точка совпадает с началом координат, то вывести 0. Если точка не совпадает с началом координат, но лежит на оси OX или OY, то вывести соответственно 1 или 2. Если точка не лежит на координатных осях, то вывести 3.

If22. Даны координаты точки, не лежащей на координатных осях OX и OY. Определить номер координатной четверти, в которой находится данная точка.

If23. Даны целочисленные координаты трех вершин прямоугольника, стороны которого параллельны координатным осям. Найти координаты его четвертой вершины.

If24. Для данного вещественного x найти значение следующей функции f, принимающей вещественные значения:

f(x) | = | 2·sin(x), | если x > 0,
 |  | 6 − x, | если x ≤ 0.

If25. Для данного целого x найти значение следующей функции f, принимающей значения целого типа:

f(x) | = | 2·x, | если x < −2 или x > 2,
 |  | −3·x | в противном случае.

If26. Для данного вещественного x найти значение следующей функции f, принимающей вещественные значения:

 |  | −x, | если x ≤ 0,
f(x) | = | x2, | если 0 < x < 2,
 |  | 4, | если x ≥ 2.

If27. Для данного вещественного x найти значение следующей функции f, принимающей значения целого типа:

 |  | 0, | если x < 0,
f(x) | = | 1, | если x принадлежит [0, 1), [2, 3), …,
 |  | −1, | если x принадлежит [1, 2), [3, 4), … .

If28. Дан номер года (положительное целое число). Определить количество дней в этом году, учитывая, что обычный год насчитывает 365 дней, а високосный — 366 дней. Високосным считается год, делящийся на 4, за исключением тех годов, которые делятся на 100 и не делятся на 400 (например, годы 300, 1300 и 1900 не являются високосными, а 1200 и 2000 — являются).


Группы заданий

Оператор выбора: группа Case

Case1. Дано целое число в диапазоне 1–7. Вывести строку — название дня недели, соответствующее данному числу (1 — «понедельник», 2 — «вторник» и т. д.).

Case2. Дано целое число K. Вывести строку-описание оценки, соответствующей числу K (1 — «плохо», 2 — «неудовлетворительно», 3 — «удовлетворительно», 4 — «хорошо», 5 — «отлично»). Если K не лежит в диапазоне 1–5, то вывести строку «ошибка».

Case3. Дан номер месяца — целое число в диапазоне 1–12 (1 — январь, 2 — февраль и т. д.). Вывести название соответствующего времени года («зима», «весна», «лето», «осень»).

Case4. Дан номер месяца — целое число в диапазоне 1–12 (1 — январь, 2 — февраль и т. д.). Определить количество дней в этом месяце для невисокосного года.

Case5. Арифметические действия над числами пронумерованы следующим образом: 1 — сложение, 2 — вычитание, 3 — умножение, 4 — деление. Дан номер действия N (целое число в диапазоне 1–4) и вещественные числа A и B (B не равно 0). Выполнить над числами указанное действие и вывести результат.

Case6. Единицы длины пронумерованы следующим образом: 1 — дециметр, 2 — километр, 3 — метр, 4 — миллиметр, 5 — сантиметр. Дан номер единицы длины (целое число в диапазоне 1–5) и длина отрезка в этих единицах (вещественное число). Найти длину отрезка в метрах.

Case7. Единицы массы пронумерованы следующим образом: 1 — килограмм, 2 — миллиграмм, 3 — грамм, 4 — тонна, 5 — центнер. Дан номер единицы массы (целое число в диапазоне 1–5) и масса тела в этих единицах (вещественное число). Найти массу тела в килограммах.

Case8. Даны два целых числа: D (день) и M (месяц), определяющие правильную дату невисокосного года. Вывести значения D и M для даты, предшествующей указанной.

Case9. Даны два целых числа: D (день) и M (месяц), определяющие правильную дату невисокосного года. Вывести значения D и M для даты, следующей за указанной.

Case10. Робот может перемещаться в четырех направлениях («С» — север, «З» — запад, «Ю» — юг, «В» — восток) и принимать три цифровые команды: 0 — продолжать движение, 1 — поворот налево, −1 — поворот направо. Дан символ C — исходное направление робота и целое число N — посланная ему команда. Вывести направление робота после выполнения полученной команды.

Case11. Локатор ориентирован на одну из сторон света («С» — север, «З» — запад, «Ю» — юг, «В» — восток) и может принимать три цифровые команды поворота: 1 — поворот налево, −1 — поворот направо, 2 — поворот на 180°. Дан символ C — исходная ориентация локатора и целые числа N1 и N2 — две посланные команды. Вывести ориентацию локатора после выполнения этих команд.

Case12. Элементы окружности пронумерованы следующим образом: 1 — радиус R, 2 — диаметр D = 2·R, 3 — длина L = 2·π·R, 4 — площадь круга S = π·R2. Дан номер одного из этих элементов и его значение. Вывести значения остальных элементов данной окружности (в том же порядке). В качестве значения π использовать 3.14.

Case13. Элементы равнобедренного прямоугольного треугольника пронумерованы следующим образом: 1 — катет a, 2 — гипотенуза c = a·(2)1/2, 3 — высота h, опущенная на гипотенузу (h = c/2), 4 — площадь S = c·h/2. Дан номер одного из этих элементов и его значение. Вывести значения остальных элементов данного треугольника (в том же порядке).

Case14. Элементы равностороннего треугольника пронумерованы следующим образом: 1 — сторона a, 2 — радиус R1 вписанной окружности (R1 = a·(3)1/2/6), 3 — радиус R2 описанной окружности (R2 = 2·R1), 4 — площадь S = a2·(3)1/2/4. Дан номер одного из этих элементов и его значение. Вывести значения остальных элементов данного треугольника (в том же порядке).

Case15. Мастям игральных карт присвоены порядковые номера: 1 — пики, 2 — трефы, 3 — бубны, 4 — червы. Достоинству карт, старших десятки, присвоены номера: 11 — валет, 12 — дама, 13 — король, 14 — туз. Даны два целых числа: N — достоинство (6 ≤ N ≤ 14) и M — масть карты (1 ≤ M ≤ 4). Вывести название соответствующей карты вида «шестерка бубен», «дама червей», «туз треф» и т. п.

Case16. Дано целое число в диапазоне 20–69, определяющее возраст (в годах). Вывести строку-описание указанного возраста, обеспечив правильное согласование числа со словом «год», например: 20 — «двадцать лет», 32 — «тридцать два года», 41 — «сорок один год».

Case17. Дано целое число в диапазоне 10–40, определяющее количество учебных заданий по некоторой теме. Вывести строку-описание указанного количества заданий, обеспечив правильное согласование числа со словами «учебное задание», например: 18 — «восемнадцать учебных заданий», 23 — «двадцать три учебных задания», 31 — «тридцать одно учебное задание».

Case18. Дано целое число в диапазоне 100–999. Вывести строку-описание данного числа, например: 256 — «двести пятьдесят шесть», 814 — «восемьсот четырнадцать».

Case19. В восточном календаре принят 60-летний цикл, состоящий из 12-летних подциклов, обозначаемых названиями цвета: зеленый, красный, желтый, белый и черный. В каждом подцикле годы носят названия животных: крысы, коровы, тигра, зайца, дракона, змеи, лошади, овцы, обезьяны, курицы, собаки и свиньи. По номеру года определить его название, если 1984 год — начало цикла: «год зеленой крысы».

Case20. Даны два целых числа: D (день) и M (месяц), определяющие правильную дату. Вывести знак Зодиака, соответствующий этой дате: «Водолей» (20.1–18.2), «Рыбы» (19.2–20.3), «Овен» (21.3–19.4), «Телец» (20.4–20.5), «Близнецы» (21.5–21.6), «Рак» (22.6–22.7), «Лев» (23.7–22.8), «Дева» (23.8–22.9), «Весы» (23.9–22.10), «Скорпион» (23.10–22.11), «Стрелец» (23.11–21.12), «Козерог» (22.12–19.1).


Группы заданий

Цикл с параметром: группа For

For1. Даны целые числа K и N (N > 0). Вывести N раз число K.

For2. Даны два целых числа A и B (A < B). Вывести в порядке возрастания все целые числа, расположенные между A и B (включая сами числа A и B), а также количество N этих чисел.

For3. Даны два целых числа A и B (A < B). Вывести в порядке убывания все целые числа, расположенные между A и B (не включая числа A и B), а также количество N этих чисел.

For4. Дано вещественное число — цена 1 кг конфет. Вывести стоимость 1, 2, …, 10 кг конфет.

For5. Дано вещественное число — цена 1 кг конфет. Вывести стоимость 0.1, 0.2, …, 1 кг конфет.

For6. Дано вещественное число — цена 1 кг конфет. Вывести стоимость 1.2, 1.4, …, 2 кг конфет.

For7. Даны два целых числа A и B (A < B). Найти сумму всех целых чисел от A до B включительно.

For8. Даны два целых числа A и B (A < B). Найти произведение всех целых чисел от A до B включительно.

For9. Даны два целых числа A и B (A < B). Найти сумму квадратов всех целых чисел от A до B включительно.

For10. Дано целое число N (> 0). Найти сумму

1 + 1/2 + 1/3 + … + 1/N

(вещественное число).

For11. Дано целое число N (> 0). Найти сумму

N2 + (N + 1)2 + (N + 2)2 + … + (2·N)2

(целое число).

For12. Дано целое число N (> 0). Найти произведение

1.1 · 1.2 · 1.3 · …

(N сомножителей).

For13. Дано целое число N (> 0). Найти значение выражения

1.1 − 1.2 + 1.3 − …

(N слагаемых, знаки чередуются). Условный оператор не использовать.

For14. Дано целое число N (> 0). Найти квадрат данного числа, используя для его вычисления следующую формулу:

N2 = 1 + 3 + 5 + … + (2·N − 1).

После добавления к сумме каждого слагаемого выводить текущее значение суммы (в результате будут выведены квадраты всех целых чисел от 1 до N).

For15. Дано вещественное число A и целое число N (> 0). Найти A в степени N:

AN = A·A· … ·A

(числа A перемножаются N раз).

For16. Дано вещественное число A и целое число N (> 0). Используя один цикл, вывести все целые степени числа A от 1 до N.

For17. Дано вещественное число A и целое число N (> 0). Используя один цикл, найти сумму

1 + A + A2 + A3 + … + AN.

For18. Дано вещественное число A и целое число N (> 0). Используя один цикл, найти значение выражения

1 − A + A2 − A3 + … + (−1)N·AN.

Условный оператор не использовать.

For19. Дано целое число N (> 0). Найти произведение

N! = 1·2·…·N

(N–факториал). Чтобы избежать целочисленного переполнения, вычислять это произведение с помощью вещественной переменной и вывести его как вещественное число.

For20. Дано целое число N (> 0). Используя один цикл, найти сумму

1! + 2! + 3! + … + N!

(выражение N! — N–факториал — обозначает произведение всех целых чисел от 1 до N: N! = 1·2·…·N). Чтобы избежать целочисленного переполнения, проводить вычисления с помощью вещественных переменных и вывести результат как вещественное число.

For21. Дано целое число N (> 0). Используя один цикл, найти сумму

1 + 1/(1!) + 1/(2!) + 1/(3!) + … + 1/(N!)

(выражение N! — N–факториал — обозначает произведение всех целых чисел от 1 до N: N! = 1·2·…·N). Полученное число является приближенным значением константы e = exp(1).

For22. Дано вещественное число X и целое число N (> 0). Найти значение выражения

1 + X + X2/(2!) + … + XN/(N!)

(N! = 1·2·…·N). Полученное число является приближенным значением функции exp в точке X.

For23. Дано вещественное число X и целое число N (> 0). Найти значение выражения

X − X3/(3!) + X5/(5!) − … + (−1)N·X2·N+1/((2·N+1)!)

(N! = 1·2·…·N). Полученное число является приближенным значением функции sin в точке X.

For24. Дано вещественное число X и целое число N (> 0). Найти значение выражения

1 − X2/(2!) + X4/(4!) − … + (−1)N·X2·N/((2·N)!)

(N! = 1·2·…·N). Полученное число является приближенным значением функции cos в точке X.

For25. Дано вещественное число X (|X| < 1) и целое число N (> 0). Найти значение выражения

X − X2/2 + X3/3 − … + (−1)N−1·XN/N.

Полученное число является приближенным значением функции ln в точке 1 + X.

For26. Дано вещественное число X (|X| < 1) и целое число N (> 0). Найти значение выражения

X − X3/3 + X5/5 − … + (−1)N·X2·N+1/(2·N+1).

Полученное число является приближенным значением функции arctg в точке X.

For27. Дано вещественное число X (|X| < 1) и целое число N (> 0). Найти значение выражения

X + 1·X3/(2·3) + 1·3·X5/(2·4·5) + … +
+ 1·3·…·(2·N−1)·X2·N+1/(2·4·…·(2·N)·(2·N+1)).

Полученное число является приближенным значением функции arcsin в точке X.

For28. Дано вещественное число X (|X| < 1) и целое число N (> 0). Найти значение выражения

1 + X/2 − 1·X2/(2·4) + 1·3·X3/(2·4·6) − … +
+ (−1)N−1·1·3·…·(2·N−3)·XN/(2·4·…·(2·N)).

Полученное число является приближенным значением функции (1+X)1/2.

For29. Дано целое число N (> 1) и две вещественные точки на числовой оси: A, B (A < B). Отрезок [A, B] разбит на N равных отрезков. Вывести H — длину каждого отрезка, а также набор точек

A, A + H, A + 2·H, A + 3·H, …, B,

образующий разбиение отрезка [A, B].

For30. Дано целое число N (> 1) и две вещественные точки на числовой оси: A, B (A < B). Отрезок [A, B] разбит на N равных отрезков. Вывести H — длину каждого отрезка, а также значения функции F(X) = 1 − sin(X) в точках, разбивающих отрезок [A, B]:

F(A), F(A + H), F(A + 2·H), …, F(B).

For31. Дано целое число N (> 0). Последовательность вещественных чисел AK определяется следующим образом:

A0 = 2, AK = 2 + 1/AK−1, K = 1, 2, … .

Вывести элементы A1, A2, …, AN.

For32. Дано целое число N (> 0). Последовательность вещественных чисел AK определяется следующим образом:

A0 = 1, AK = (AK−1 + 1)/K, K = 1, 2, … .

Вывести элементы A1, A2, …, AN.

For33. Дано целое число N (> 1). Последовательность чисел Фибоначчи FK (целого типа) определяется следующим образом:

F1 = 1, F2 = 1, FK = FK−2 + FK−1, K = 3, 4, … .

Вывести элементы F1, F2, …, FN.

For34. Дано целое число N (> 1). Последовательность вещественных чисел AK определяется следующим образом:

A1 = 1, A2 = 2, AK = (AK−2 + 2·AK−1)/3, K = 3, 4, … .

Вывести элементы A1, A2, …, AN.

For35. Дано целое число N (> 2). Последовательность целых чисел AK определяется следующим образом:

A1 = 1, A2 = 2, A3 = 3, AK = AK−1 + AK−2 − 2·AK−3, K = 4, 5, … .

Вывести элементы A1, A2, …, AN.

Цикл с параметром: вложенные циклы

For36. Даны целые положительные числа N и K. Найти сумму

1K + 2K + … + NK.

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

For37. Дано целое число N (> 0). Найти сумму

11 + 22 + … + NN.

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

For38. Дано целое число N (> 0). Найти сумму

1N + 2N−1 + … + N1.

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

For39. Даны целые положительные числа A и B (A < B). Вывести все целые числа от A до B включительно; при этом каждое число должно выводиться столько раз, каково его значение (например, число 3 выводится 3 раза).

For40. Даны целые числа A и B (A < B). Вывести все целые числа от A до B включительно; при этом число A должно выводиться 1 раз, число A + 1 должно выводиться 2 раза и т. д.


Группы заданий

Цикл с условием: группа While

While1. Даны положительные числа A и B (A > B). На отрезке длины A размещено максимально возможное количество отрезков длины B (без наложений). Не используя операции умножения и деления, найти длину незанятой части отрезка A.

While2. Даны положительные числа A и B (A > B). На отрезке длины A размещено максимально возможное количество отрезков длины B (без наложений). Не используя операции умножения и деления, найти количество отрезков B, размещенных на отрезке A.

While3. Даны целые положительные числа N и K. Используя только операции сложения и вычитания, найти частное от деления нацело N на K, а также остаток от этого деления.

While4. Дано целое число N (> 0). Если оно является степенью числа 3, то вывести true, если не является — вывести false.

While5. Дано целое число N (> 0), являющееся некоторой степенью числа 2: N = 2K. Найти целое число K — показатель этой степени.

While6. Дано целое число N (> 0). Найти двойной факториал N:

N!! = N·(N−2)·(N−4)·…

(последний сомножитель равен 2, если N — четное, и 1, если N — нечетное). Чтобы избежать целочисленного переполнения, вычислять это произведение с помощью вещественной переменной и вывести его как вещественное число.

While7. Дано целое число N (> 0). Найти наименьшее целое положительное число K, квадрат которого превосходит N: K2 > N. Функцию извлечения квадратного корня не использовать.

While8. Дано целое число N (> 0). Найти наибольшее целое число K, квадрат которого не превосходит N: K2 ≤ N. Функцию извлечения квадратного корня не использовать.

While9. Дано целое число N (> 1). Найти наименьшее целое число K, при котором выполняется неравенство 3K > N.

While10. Дано целое число N (> 1). Найти наибольшее целое число K, при котором выполняется неравенство 3K < N.

While11. Дано целое число N (> 1). Вывести наименьшее из целых чисел K, для которых сумма 1 + 2 + … + K будет больше или равна N, и саму эту сумму.

While12. Дано целое число N (> 1). Вывести наибольшее из целых чисел K, для которых сумма 1 + 2 + … + K будет меньше или равна N, и саму эту сумму.

While13. Дано число A (> 1). Вывести наименьшее из целых чисел K, для которых сумма 1 + 1/2 + … + 1/K будет больше A, и саму эту сумму.

While14. Дано число A (> 1). Вывести наибольшее из целых чисел K, для которых сумма 1 + 1/2 + … + 1/K будет меньше A, и саму эту сумму.

While15. Начальный вклад в банке равен 1000 руб. В конце каждого месяца размер вклада увеличивается на P процентов от имеющейся суммы (P — вещественное число, 0 < P < 25). По данному P определить, через сколько месяцев размер вклада превысит 1100 руб., и вывести найденное количество месяцев K (целое число) и итоговый размер вклада S (вещественное число).

While16. Спортсмен-лыжник начал тренировки, пробежав в первый день 10 км. Каждый следующий день он увеличивал длину пробега на P процентов от пробега предыдущего дня (P — вещественное, 0 < P < 50). По данному P определить, после какого дня суммарный пробег лыжника за все дни превысит 200 км, и вывести найденное количество дней K (целое) и суммарный пробег S (вещественное число).

While17. Дано целое число N (> 0). Используя операции деления нацело и взятия остатка от деления, вывести все его цифры, начиная с самой правой (разряда единиц).

While18. Дано целое число N (> 0). Используя операции деления нацело и взятия остатка от деления, найти количество и сумму его цифр.

While19. Дано целое число N (> 0). Используя операции деления нацело и взятия остатка от деления, найти число, полученное при прочтении числа N справа налево.

While20. Дано целое число N (> 0). С помощью операций деления нацело и взятия остатка от деления определить, имеется ли в записи числа N цифра «2». Если имеется, то вывести true, если нет — вывести false.

While21. Дано целое число N (> 0). С помощью операций деления нацело и взятия остатка от деления определить, имеются ли в записи числа N нечетные цифры. Если имеются, то вывести true, если нет — вывести false.

While22. Дано целое число N (> 1). Если оно является простым, то есть не имеет положительных делителей, кроме 1 и самого себя, то вывести true, иначе вывести false.

While23. Даны целые положительные числа A и B. Найти их наибольший общий делитель (НОД), используя алгоритм Евклида:

НОД(A, B) = НОД(B, A mod B), если B ≠ 0; НОД(A, 0) = A,

где «mod» обозначает операцию взятия остатка от деления.

While24. Дано целое число N (> 1). Последовательность чисел Фибоначчи FK определяется следующим образом:

F1 = 1, F2 = 1, FK = FK−2 + FK−1, K = 3, 4, … .

Проверить, является ли число N числом Фибоначчи. Если является, то вывести true, если нет — вывести false.

While25. Дано целое число N (> 1). Найти первое число Фибоначчи, большее N (определение чисел Фибоначчи дано в задании While24).

While26. Дано целое число N (> 1), являющееся числом Фибоначчи: N = FK (определение чисел Фибоначчи дано в задании While24). Найти целые числа FK−1 и FK+1 — предыдущее и последующее числа Фибоначчи.

While27. Дано целое число N (> 1), являющееся числом Фибоначчи: N = FK (определение чисел Фибоначчи дано в задании While24). Найти целое число K — порядковый номер числа Фибоначчи N.

While28. Дано вещественное число ε (> 0). Последовательность вещественных чисел AK определяется следующим образом:

A1 = 2, AK = 2 + 1/AK−1, K = 2, 3, … .

Найти первый из номеров K, для которых выполняется условие |AK − AK−1| < ε, и вывести этот номер, а также числа AK−1 и AK.

While29. Дано вещественное число ε (> 0). Последовательность вещественных чисел AK определяется следующим образом:

A1 = 1, A2 = 2, AK = (AK−2 + 2·AK−1)/3, K = 3, 4, … .

Найти первый из номеров K, для которых выполняется условие |AK − AK−1| < ε, и вывести этот номер, а также числа AK−1 и AK.

While30. Даны положительные числа A, B, C. На прямоугольнике размера A × B размещено максимально возможное количество квадратов со стороной C (без наложений). Найти количество квадратов, размещенных на прямоугольнике. Операции умножения и деления не использовать.


Группы заданий

Процедуры и функции: группа Proc

Процедуры с числовыми параметрами

Proc1. Описать процедуру PowerA3(A, B), вычисляющую третью степень числа A и возвращающую ее в переменной B (A — входной, B — выходной параметр; оба параметра являются вещественными). С помощью этой процедуры найти третьи степени пяти данных чисел.

Proc2. Описать процедуру PowerA234(A, B, C, D), вычисляющую вторую, третью и четвертую степень числа A и возвращающую эти степени соответственно в переменных B, C и D (A — входной, B, C, D — выходные параметры; все параметры являются вещественными). С помощью этой процедуры найти вторую, третью и четвертую степень пяти данных чисел.

Proc3. Описать процедуру Mean(X, Y, AMean, GMean), вычисляющую среднее арифметическое AMean = (X+Y)/2 и среднее геометрическое GMean = (X·Y)1/2 двух положительных чисел X и Y (X и Y — входные, AMean и GMean — выходные параметры вещественного типа). С помощью этой процедуры найти среднее арифметическое и среднее геометрическое для пар (A, B), (A, C), (A, D), если даны A, B, C, D.

Proc4. Описать процедуру TrianglePS(a, P, S), вычисляющую по стороне a равностороннего треугольника его периметр P = 3·a и площадь S = a2·(3)1/2/4 (a — входной, P и S — выходные параметры; все параметры являются вещественными). С помощью этой процедуры найти периметры и площади трех равносторонних треугольников с данными сторонами.

Proc5. Описать процедуру RectPS(x1, y1, x2, y2, P, S), вычисляющую периметр P и площадь S прямоугольника со сторонами, параллельными осям координат, по координатам (x1, y1), (x2, y2) его противоположных вершин (x1, y1, x2, y2 — входные, P и S — выходные параметры вещественного типа). С помощью этой процедуры найти периметры и площади трех прямоугольников с данными противоположными вершинами.

Proc6. Описать процедуру DigitCountSum(K, C, S), находящую количество C цифр целого положительного числа K, а также их сумму S (K — входной, C и S — выходные параметры целого типа). С помощью этой процедуры найти количество и сумму цифр для каждого из пяти данных целых чисел.

Proc7. Описать процедуру InvDigits(K), меняющую порядок следования цифр целого положительного числа K на обратный (K — параметр целого типа, являющийся одновременно входным и выходным). С помощью этой процедуры поменять порядок следования цифр на обратный для каждого из пяти данных целых чисел.

Proc8. Описать процедуру AddRightDigit(D, K), добавляющую к целому положительному числу K справа цифру D (D — входной параметр целого типа, лежащий в диапазоне 0–9, K — параметр целого типа, являющийся одновременно входным и выходным). С помощью этой процедуры последовательно добавить к данному числу K справа данные цифры D1 и D2, выводя результат каждого добавления.

Proc9. Описать процедуру AddLeftDigit(D, K), добавляющую к целому положительному числу K слева цифру D (D — входной параметр целого типа, лежащий в диапазоне 1–9, K — параметр целого типа, являющийся одновременно входным и выходным). С помощью этой процедуры последовательно добавить к данному числу K слева данные цифры D1 и D2, выводя результат каждого добавления.

Proc10. Описать процедуру Swap(X, Y), меняющую содержимое переменных X и Y (X и Y — вещественные параметры, являющиеся одновременно входными и выходными). С ее помощью для данных переменных A, B, C, D последовательно поменять содержимое следующих пар: A и B, C и D, B и C и вывести новые значения A, B, C, D.

Proc11. Описать процедуру Minmax(X, Y), записывающую в переменную X минимальное из значений X и Y, а в переменную Y — максимальное из этих значений (X и Y — вещественные параметры, являющиеся одновременно входными и выходными). Используя четыре вызова этой процедуры, найти минимальное и максимальное из данных чисел A, B, C, D.

Proc12. Описать процедуру SortInc3(A, B, C), меняющую содержимое переменных A, B, C таким образом, чтобы их значения оказались упорядоченными по возрастанию (A, B, C — вещественные параметры, являющиеся одновременно входными и выходными). С помощью этой процедуры упорядочить по возрастанию два данных набора из трех чисел: (A1, B1, C1) и (A2, B2, C2).

Proc13. Описать процедуру SortDec3(A, B, C), меняющую содержимое переменных A, B, C таким образом, чтобы их значения оказались упорядоченными по убыванию (A, B, C — вещественные параметры, являющиеся одновременно входными и выходными). С помощью этой процедуры упорядочить по убыванию два данных набора из трех чисел: (A1, B1, C1) и (A2, B2, C2).

Proc14. Описать процедуру ShiftRight3(A, B, C), выполняющую правый циклический сдвиг: значение A переходит в B, значение B — в C, значение C — в A (A, B, C — вещественные параметры, являющиеся одновременно входными и выходными). С помощью этой процедуры выполнить правый циклический сдвиг для двух данных наборов из трех чисел: (A1, B1, C1) и (A2, B2, C2).

Proc15. Описать процедуру ShiftLeft3(A, B, C), выполняющую левый циклический сдвиг: значение A переходит в C, значение C — в B, значение B — в A (A, B, C — вещественные параметры, являющиеся одновременно входными и выходными). С помощью этой процедуры выполнить левый циклический сдвиг для двух данных наборов из трех чисел: (A1, B1, C1) и (A2, B2, C2).

Функции с числовыми параметрами

Proc16. Описать функцию Sign(X) целого типа, возвращающую для вещественного числа X следующие значения:

−1, если X < 0; 0, если X = 0; 1, если X > 0.

С помощью этой функции найти значение выражения Sign(A) + Sign(B) для данных вещественных чисел A и B.

Proc17. Описать функцию RootCount(A, B, C) целого типа, определяющую количество корней квадратного уравнения A·x2 + B·x + C = 0 (A, B, C — вещественные параметры, A ≠ 0). С ее помощью найти количество корней для каждого из трех квадратных уравнений с данными коэффициентами. Количество корней определять по значению дискриминанта:

D = B2 − 4·A·C.

Proc18. Описать функцию CircleS(R) вещественного типа, находящую площадь круга радиуса R (R — вещественное). С помощью этой функции найти площади трех кругов с данными радиусами. Площадь круга радиуса R вычисляется по формуле S = π·R2. В качестве значения π использовать 3.14.

Proc19. Описать функцию RingS(R1, R2) вещественного типа, находящую площадь кольца, заключенного между двумя окружностями с общим центром и радиусами R1 и R2 (R1 и R2 — вещественные, R1 > R2). С ее помощью найти площади трех колец, для которых даны внешние и внутренние радиусы. Воспользоваться формулой площади круга радиуса R: S = π·R2. В качестве значения π использовать 3.14.

Proc20. Описать функцию TriangleP(a, h), находящую периметр равнобедренного треугольника по его основанию a и высоте h, проведенной к основанию (a и h — вещественные). С помощью этой функции найти периметры трех треугольников, для которых даны основания и высоты. Для нахождения боковой стороны b треугольника использовать теорему Пифагора:

b2 = (a/2)2 + h2.

Proc21. Описать функцию SumRange(A, B) целого типа, находящую сумму всех целых чисел от A до B включительно (A и B — целые). Если A > B, то функция возвращает 0. С помощью этой функции найти суммы чисел от A до B и от B до C, если даны числа A, B, C.

Proc22. Описать функцию Calc(A, B, Op) вещественного типа, выполняющую над ненулевыми вещественными числами A и B одну из арифметических операций и возвращающую ее результат. Вид операции определяется целым параметром Op: 1 — вычитание, 2 — умножение, 3 — деление, остальные значения — сложение. С помощью Calc выполнить для данных A и B операции, определяемые данными целыми N1, N2, N3.

Proc23. Описать функцию Quarter(x, y) целого типа, определяющую номер координатной четверти, в которой находится точка с ненулевыми вещественными координатами (x, y). С помощью этой функции найти номера координатных четвертей для трех точек с данными ненулевыми координатами.

Proc24. Описать функцию Even(K) логического типа, возвращающую True, если целый параметр K является четным, и False в противном случае. С ее помощью найти количество четных чисел в наборе из 10 целых чисел.

Proc25. Описать функцию IsSquare(K) логического типа, возвращающую True, если целый параметр K (> 0) является квадратом некоторого целого числа, и False в противном случае. С ее помощью найти количество квадратов в наборе из 10 целых положительных чисел.

Proc26. Описать функцию IsPower5(K) логического типа, возвращающую True, если целый параметр K (> 0) является степенью числа 5, и False в противном случае. С ее помощью найти количество степеней числа 5 в наборе из 10 целых положительных чисел.

Proc27. Описать функцию IsPowerN(K, N) логического типа, возвращающую True, если целый параметр K (> 0) является степенью числа N (> 1), и False в противном случае. Дано число N (> 1) и набор из 10 целых положительных чисел. С помощью функции IsPowerN найти количество степеней числа N в данном наборе.

Proc28. Описать функцию IsPrime(N) логического типа, возвращающую True, если целый параметр N (> 1) является простым числом, и False в противном случае (число, большее 1, называется простым, если оно не имеет положительных делителей, кроме 1 и самого себя). Дан набор из 10 целых чисел, больших 1. С помощью функции IsPrime найти количество простых чисел в данном наборе.

Proc29. Описать функцию DigitCount(K) целого типа, находящую количество цифр целого положительного числа K. Используя эту функцию, найти количество цифр для каждого из пяти данных целых положительных чисел.

Proc30. Описать функцию DigitN(K, N) целого типа, возвращающую N-ю цифру целого положительного числа K (цифры в числе нумеруются справа налево). Если количество цифр в числе K меньше N, то функция возвращает −1. Для каждого из пяти данных целых положительных чисел K1, K2, …, K5 вызвать функцию DigitN с параметром N, изменяющимся от 1 до 5.

Proc31. Описать функцию IsPalindrome(K), возвращающую True, если целый параметр K (> 0) является палиндромом (т. е. его запись читается одинаково слева направо и справа налево), и False в противном случае. С ее помощью найти количество палиндромов в наборе из 10 целых положительных чисел.

Proc32. Описать функцию DegToRad(D) вещественного типа, находящую величину угла в радианах, если дана его величина D в градусах (D — вещественное число, 0 ≤ D < 360). Воспользоваться следующим соотношением: 180° = π радианов. В качестве значения π использовать 3.14. С помощью функции DegToRad перевести из градусов в радианы пять данных углов.

Proc33. Описать функцию RadToDeg(R) вещественного типа, находящую величину угла в градусах, если дана его величина R в радианах (R — вещественное число, 0 ≤ R < 2·π). Воспользоваться следующим соотношением: 180° = π радианов. В качестве значения π использовать 3.14. С помощью функции RadToDeg перевести из радианов в градусы пять данных углов.

Proc34. Описать функцию Fact(N) вещественного типа, вычисляющую значение факториала N! = 1·2·…·N (N > 0 — параметр целого типа; вещественное возвращаемое значение используется для того, чтобы избежать целочисленного переполнения при больших значениях N). С помощью этой функции найти факториалы пяти данных целых чисел.

Proc35. Описать функцию Fact2(N) вещественного типа, вычисляющую двойной факториал:

N!! = 1·3·5·…·N, если N — нечетное;
N!! = 2·4·6·…·N, если N — четное

(N > 0 — параметр целого типа; вещественное возвращаемое значение используется для того, чтобы избежать целочисленного переполнения при больших значениях N). С помощью этой функции найти двойные факториалы пяти данных целых чисел.

Proc36. Описать функцию Fib(N) целого типа, вычисляющую N-й элемент последовательности чисел Фибоначчи FK, которая описывается следующими формулами:

F1 = 1, F2 = 1, FK = FK−2 + FK−1, K = 3, 4, … .

Используя функцию Fib, найти пять чисел Фибоначчи с данными номерами N1, N2, …, N5.

Дополнительные задания на процедуры и функции

Proc37. Описать функцию Power1(A, B) вещественного типа, находящую величину AB по формуле AB = exp(B·ln(A)) (параметры A и B — вещественные). В случае нулевого или отрицательного параметра A функция возвращает 0. С помощью этой функции найти степени AP, BP, CP, если даны числа P, A, B, C.

Proc38. Описать функцию Power2(A, N) вещественного типа, находящую величину AN (A — вещественный, N — целый параметр) по следующим формулам:

A0 = 1;
AN = A·A·…·A (N сомножителей), если N > 0;
AN = 1/(A·A·…·A) (|N| сомножителей), если N < 0.

С помощью этой функции найти AK, AL, AM, если даны числа A, K, L, M.

Proc39. Используя функции Power1 и Power2 из Proc37 и Proc38, описать функцию Power3(A, B) вещественного типа с вещественными параметрами, находящую AB следующим образом: если B имеет нулевую дробную часть, то вызывается Power2(A, N), где N — переменная целого типа, равная числу B; иначе вызывается Power1(A, B). С помощью Power3 найти AP, BP, CP, если даны числа P, A, B, C.

Proc40. Описать функцию Exp1(x, ε) вещественного типа (параметры x, ε — вещественные, ε > 0), находящую приближенное значение функции exp(x):

exp(x) = 1 + x + x2/(2!) + x3/(3!) + … + xn/(n!) + …

(n! = 1·2·…·n). В сумме учитывать все слагаемые, большие ε. С помощью Exp1 найти приближенное значение экспоненты для данного x при шести данных ε.

Proc41. Описать функцию Sin1(x, ε) вещественного типа (параметры x, ε — вещественные, ε > 0), находящую приближенное значение функции sin(x):

sin(x) = x − x3/(3!) + x5/(5!) − … + (−1)n·x2·n+1/((2·n+1)!) + … .

В сумме учитывать все слагаемые, модуль которых больше ε. С помощью Sin1 найти приближенное значение синуса для данного x при шести данных ε.

Proc42. Описать функцию Cos1(x, ε) вещественного типа (параметры x, ε — вещественные, ε > 0), находящую приближенное значение функции cos(x):

cos(x) = 1 − x2/(2!) + x4/(4!) − … + (−1)n·x2·n/((2·n)!) + … .

В сумме учитывать все слагаемые, модуль которых больше ε. С помощью Cos1 найти приближенное значение косинуса для данного x при шести данных ε.

Proc43. Описать функцию Ln1(x, ε) вещественного типа (параметры x, ε — вещественные, |x| < 1, ε > 0), находящую приближенное значение функции ln(1 + x):

ln(1 + x) = x − x2/2 + x3/3 − … + (−1)n·xn+1/(n+1) + … .

В сумме учитывать все слагаемые, модуль которых больше ε. С помощью Ln1 найти приближенное значение ln(1 + x) для данного x при шести данных ε.

Proc44. Описать функцию Arctg1(x, ε) вещественного типа (параметры x, ε — вещественные, |x| < 1, ε > 0), находящую приближенное значение функции arctg(x):

arctg(x) = x − x3/3 + x5/5 − … + (−1)n·x2·n+1/(2·n+1) + … .

В сумме учитывать все слагаемые, модуль которых больше ε. С помощью Arctg1 найти приближенное значение arctg(x) для данного x при шести данных ε.

Proc45. Описать функцию Power4(x, a, ε) вещественного типа (параметры x, a, ε — вещественные, |x| < 1; a, ε > 0), находящую приближенное значение функции (1 + x)a:

(1 + x)a = 1 + a·x + a·(a−1)·x2/(2!) + … + a·(a−1)·…·(a−n+1)·xn/(n!) + … .

В сумме учитывать все слагаемые, модуль которых больше ε. С помощью Power4 найти приближенное значение (1 + x)a для данных x и a при шести данных ε.

Proc46. Описать функцию GCD2(A, B) целого типа, находящую наибольший общий делитель (НОД, greatest common divisor) двух целых положительных чисел A и B, используя алгоритм Евклида:

НОД(A, B) = НОД(B, A mod B), если B ≠ 0; НОД(A, 0) = A,

где «mod» обозначает операцию взятия остатка от деления. С помощью GCD2 найти наибольшие общие делители пар (A, B), (A, C), (A, D), если даны числа A, B, C, D.

Proc47. Используя функцию GCD2 (см. Proc46), описать процедуру Frac1(a, b, p, q), преобразующую дробь a/b к несократимому виду p/q (все параметры процедуры — целого типа, a и b — входные, p и q — выходные). Знак результирующей дроби p/q приписывается числителю (т. е. q > 0). С помощью Frac1 найти несократимые дроби, равные a/b + c/d, a/b + e/f, a/b + g/h (числа a, b, c, d, e, f, g, h даны).

Proc48. Наименьшее общее кратное (least common multiple) двух целых положительных чисел A и B равно A·(B/НОД(A, B)), где НОД(A, B) — наибольший общий делитель A и B. Используя функцию GCD2 (см. Proc46), описать функцию LCM2(A, B) целого типа, находящую наименьшее общее кратное чисел A и B. С помощью LCM2 найти наименьшие общие кратные пар (A, B), (A, C), (A, D), если даны числа A, B, C, D.

Proc49. Учитывая соотношение НОД(A, B, C) = НОД(НОД(A, B), C) и используя функцию GCD2 (см. Proc46), описать функцию GCD3(A, B, C) целого типа, находящую наибольший общий делитель трех целых положительных чисел A, B, C. С помощью GCD3 найти наибольшие общие делители троек (A, B, C), (A, C, D) и (B, C, D), если даны числа A, B, C, D.

Proc50. Описать процедуру TimeToHMS(T, H, M, S), определяющую по времени T (в секундах) содержащееся в нем количество часов H, минут M и секунд S (T — входной, H, M и S — выходные параметры целого типа). Используя эту процедуру, найти количество часов, минут и секунд для пяти данных отрезков времени T1, T2, …, T5.

Proc51. Описать процедуру IncTime(H, M, S, T), которая увеличивает на T секунд время, заданное в часах H, минутах M и секундах S (H, M и S — входные и выходные параметры, T — входной параметр; все параметры — целые положительные). Дано время (в часах H, минутах M, секундах S) и целое число T. Используя процедуру IncTime, увеличить данное время на T секунд и вывести новые значения H, M, S.

Proc52. Описать функцию IsLeapYear(Y) логического типа, которая возвращает True, если год Y (целое положительное число) является високосным, и False в противном случае. Вывести значение функции IsLeapYear для пяти данных значений параметра Y. Високосным считается год, делящийся на 4, за исключением тех годов, которые делятся на 100 и не делятся на 400.

Proc53. Используя функцию IsLeapYear из задания Proc52, описать функцию MonthDays(M, Y) целого типа, которая возвращает количество дней для M-го месяца года Y (1 ≤ M ≤ 12, Y > 0 — целые числа). Вывести значение функции MonthDays для данного года Y и месяцев M1, M2, M3.

Proc54. Используя функцию MonthDays из задания Proc53, описать процедуру PrevDate(D, M, Y), которая по информации о правильной дате, включающей день D, номер месяца M и год Y, определяет предыдущую дату (параметры целого типа D, M, Y являются одновременно входными и выходными). Применить процедуру PrevDate к трем исходным датам и вывести полученные значения предыдущих дат.

Proc55. Используя функцию MonthDays из задания Proc53, описать процедуру NextDate(D, M, Y), которая по информации о правильной дате, включающей день D, номер месяца M и год Y, определяет следующую дату (параметры целого типа D, M, Y являются одновременно входными и выходными). Применить процедуру NextDate к трем исходным датам и вывести полученные значения следующих дат.

Proc56. Описать функцию Leng(xA, yA, xB, yB) вещественного типа, находящую длину отрезка AB на плоскости по координатам его концов:

|AB| = ((xA − xB)2 + (yA − yB)2)1/2

(xA, yA, xB, yB — вещественные параметры). С помощью этой функции найти длины отрезков AB, AC, AD, если даны координаты точек A, B, C, D.

Proc57. Используя функцию Leng из задания Proc56, описать функцию Perim(xA, yA, xB, yB, xC, yC) вещественного типа, находящую периметр треугольника ABC по координатам его вершин (xA, yA, xB, yB, xC, yC — вещественные параметры). С помощью этой функции найти периметры треугольников ABC, ABD, ACD, если даны координаты точек A, B, C, D.

Proc58. Используя функции Leng и Perim из заданий Proc56 и Proc57, описать функцию Area(xA, yA, xB, yB, xC, yC) вещественного типа, находящую площадь треугольника ABC по формуле

SABC = (p·(p−|AB|)·(p−|AC|)·(p−|BC|))1/2,

где p — полупериметр. С помощью этой функции найти площади треугольников ABC, ABD, ACD, если даны координаты точек A, B, C, D.

Proc59. Используя функции Leng и Area из заданий Proc56 и Proc58, описать функцию Dist(xP, yP, xA, yA, xB, yB) вещественного типа, находящую расстояние D(P, AB) от точки P до прямой AB по формуле

D(P, AB) = 2·SPAB/|AB|,

где SPAB — площадь треугольника PAB. С помощью этой функции найти расстояния от точки P до прямых AB, AC, BC, если даны координаты точек P, A, B, C.

Proc60. Используя функцию Dist из задания Proc59, описать процедуру Altitudes(xA, yA, xB, yB, xC, yC, hA, hB, hC), находящую высоты hA, hB, hC треугольника ABC (выходные параметры), проведенные соответственно из вершин A, B, C (их координаты являются входными параметрами). С помощью этой процедуры найти высоты треугольников ABC, ABD, ACD, если даны координаты точек A, B, C, D.


Группы заданий

Последовательности: группа Series

Во всех заданиях данной группы предполагается, что исходный набор содержит ненулевое число элементов (в частности, число N всегда больше нуля). В заданиях на обработку нескольких наборов чисел количество наборов K также всегда является ненулевым.

Series1. Даны десять вещественных чисел. Найти их сумму.

Series2. Даны десять вещественных чисел. Найти их произведение.

Series3. Даны десять вещественных чисел. Найти их среднее арифметическое.

Series4. Дано целое число N и набор из N вещественных чисел. Вывести сумму и произведение чисел из данного набора.

Series5. Дано целое число N и набор из N положительных вещественных чисел. Вывести в том же порядке целые части всех чисел из данного набора (как вещественные числа с нулевой дробной частью), а также сумму всех целых частей.

Series6. Дано целое число N и набор из N положительных вещественных чисел. Вывести в том же порядке дробные части всех чисел из данного набора (как вещественные числа с нулевой целой частью), а также произведение всех дробных частей.

Series7. Дано целое число N и набор из N вещественных чисел. Вывести в том же порядке округленные значения всех чисел из данного набора (как целые числа), а также сумму всех округленных значений.

Series8. Дано целое число N и набор из N целых чисел. Вывести в том же порядке все четные числа из данного набора и количество K таких чисел.

Series9. Дано целое число N и набор из N целых чисел. Вывести в том же порядке номера всех нечетных чисел из данного набора и количество K таких чисел.

Series10. Дано целое число N и набор из N целых чисел. Если в наборе имеются положительные числа, то вывести True; в противном случае вывести False.

Series11. Даны целые числа K, N и набор из N целых чисел. Если в наборе имеются числа, меньшие K, то вывести True; в противном случае вывести False.

Series12. Дан набор ненулевых целых чисел; признак его завершения — число 0. Вывести количество чисел в наборе.

Series13. Дан набор ненулевых целых чисел; признак его завершения — число 0. Вывести сумму всех положительных четных чисел из данного набора. Если требуемые числа в наборе отсутствуют, то вывести 0.

Series14. Дано целое число K и набор ненулевых целых чисел; признак его завершения — число 0. Вывести количество чисел в наборе, меньших K.

Series15. Дано целое число K и набор ненулевых целых чисел; признак его завершения — число 0. Вывести номер первого числа в наборе, большего K. Если таких чисел нет, то вывести 0.

Series16. Дано целое число K и набор ненулевых целых чисел; признак его завершения — число 0. Вывести номер последнего числа в наборе, большего K. Если таких чисел нет, то вывести 0.

Series17. Дано вещественное число B, целое число N и набор из N вещественных чисел, упорядоченных по возрастанию. Вывести элементы набора вместе с числом B, сохраняя упорядоченность выводимых чисел.

Series18. Дано целое число N и набор из N целых чисел, упорядоченный по возрастанию. Данный набор может содержать одинаковые элементы. Вывести в том же порядке все различные элементы данного набора.

Series19. Дано целое число N (> 1) и набор из N целых чисел. Вывести те элементы в наборе, которые меньше своего левого соседа, и количество K таких элементов.

Series20. Дано целое число N (> 1) и набор из N целых чисел. Вывести те элементы в наборе, которые меньше своего правого соседа, и количество K таких элементов.

Series21. Дано целое число N (> 1) и набор из N вещественных чисел. Проверить, образует ли данный набор возрастающую последовательность. Если образует, то вывести True, если нет — вывести False.

Series22. Дано целое число N (> 1) и набор из N вещественных чисел. Если данный набор образует убывающую последовательность, то вывести 0; в противном случае вывести номер первого числа, нарушающего закономерность.

Series23. Дано целое число N (> 2) и набор из N вещественных чисел. Набор называется пилообразным, если каждый его внутренний элемент либо больше, либо меньше обоих своих соседей (т. е. является «зубцом»). Если данный набор является пилообразным, то вывести 0; в противном случае вывести номер первого элемента, не являющегося зубцом.

Series24. Дано целое число N и набор из N целых чисел, содержащий по крайней мере два нуля. Вывести сумму чисел из данного набора, расположенных между последними двумя нулями (если последние нули идут подряд, то вывести 0).

Series25. Дано целое число N и набор из N целых чисел, содержащий по крайней мере два нуля. Вывести сумму чисел из данного набора, расположенных между первым и последним нулем (если первый и последний нули идут подряд, то вывести 0).

Последовательности: вложенные циклы

Series26. Даны целые числа K, N и набор из N вещественных чисел: A1, A2, …, AN. Вывести K-e степени чисел из данного набора:

(A1)K, (A2)K, …, (AN)K.

Series27. Дано целое число N и набор из N вещественных чисел: A1, A2, …, AN. Вывести следующие числа:

A1, (A2)2, …, (AN−1)N−1, (AN)N.

Series28. Дано целое число N и набор из N вещественных чисел: A1, A2, …, AN. Вывести следующие числа:

(A1)N, (A2)N−1, …, (AN−1)2, AN.

Series29. Даны целые числа K, N, а также K наборов целых чисел по N элементов в каждом наборе. Вывести общую сумму всех элементов, входящих в данные наборы.

Series30. Даны целые числа K, N, а также K наборов целых чисел по N элементов в каждом наборе. Для каждого набора вывести сумму его элементов.

Series31. Даны целые числа K, N, а также K наборов целых чисел по N элементов в каждом наборе. Найти количество наборов, содержащих число 2. Если таких наборов нет, то вывести 0.

Series32. Даны целые числа K, N, а также K наборов целых чисел по N элементов в каждом наборе. Для каждого набора вывести номер его первого элемента, равного 2, или число 0, если в данном наборе нет двоек.

Series33. Даны целые числа K, N, а также K наборов целых чисел по N элементов в каждом наборе. Для каждого набора вывести номер его последнего элемента, равного 2, или число 0, если в данном наборе нет двоек.

Series34. Даны целые числа K, N, а также K наборов целых чисел по N элементов в каждом наборе. Для каждого набора выполнить следующее действие: если в наборе содержится число 2, то вывести сумму его элементов; если в наборе нет двоек, то вывести 0.

Series35. Дано целое число K, а также K наборов ненулевых целых чисел. Признаком завершения каждого набора является число 0. Для каждого набора вывести количество его элементов. Вывести также общее количество элементов во всех наборах.

Series36. Дано целое число K, а также K наборов ненулевых целых чисел. Каждый набор содержит не менее двух элементов, признаком его завершения является число 0. Найти количество наборов, элементы которых возрастают.

Series37. Дано целое число K, а также K наборов ненулевых целых чисел. Каждый набор содержит не менее двух элементов, признаком его завершения является число 0. Найти количество наборов, элементы которых возрастают или убывают.

Series38. Дано целое число K, а также K наборов ненулевых целых чисел. Каждый набор содержит не менее двух элементов, признаком его завершения является число 0. Для каждого набора выполнить следующее действие: если элементы набора возрастают, то вывести 1; если элементы набора убывают, то вывести −1; если элементы набора не возрастают и не убывают, то вывести 0.

Series39. Дано целое число K, а также K наборов ненулевых целых чисел. Каждый набор содержит не менее трех элементов, признаком его завершения является число 0. Найти количество пилообразных наборов (определение пилообразного набора дано в задании Series23).

Series40. Дано целое число K, а также K наборов ненулевых целых чисел. Каждый набор содержит не менее трех элементов, признаком его завершения является число 0. Для каждого набора выполнить следующее действие: если набор является пилообразным (см. задание Series23), то вывести количество его элементов; в противном случае вывести номер первого элемента, который не является зубцом.


Группы заданий

Минимумы и максимумы: группа Minmax

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

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

Minmax1. Дано целое число N и набор из N чисел. Найти минимальный и максимальный из элементов данного набора и вывести их в указанном порядке.

Minmax2. Дано целое число N и набор из N прямоугольников, заданных своими сторонами — парами чисел (a, b). Найти минимальную площадь прямоугольника из данного набора.

Minmax3. Дано целое число N и набор из N прямоугольников, заданных своими сторонами — парами чисел (a, b). Найти максимальный периметр прямоугольника из данного набора.

Minmax4. Дано целое число N и набор из N чисел. Найти номер минимального элемента из данного набора.

Minmax5. Дано целое число N и набор из N пар чисел (m, v) — данные о массе m и объеме v деталей, изготовленных из различных материалов. Вывести номер детали, изготовленной из материала максимальной плотности, а также величину этой максимальной плотности. Плотность P вычисляется по формуле

P = m/v.

Minmax6. Дано целое число N и набор из N целых чисел. Найти номера первого минимального и последнего максимального элемента из данного набора и вывести их в указанном порядке.

Minmax7. Дано целое число N и набор из N целых чисел. Найти номера первого максимального и последнего минимального элемента из данного набора и вывести их в указанном порядке.

Minmax8. Дано целое число N и набор из N целых чисел. Найти номера первого и последнего минимального элемента из данного набора и вывести их в указанном порядке.

Minmax9. Дано целое число N и набор из N целых чисел. Найти номера первого и последнего максимального элемента из данного набора и вывести их в указанном порядке.

Minmax10. Дано целое число N и набор из N целых чисел. Найти номер первого экстремального (т. е. минимального или максимального) элемента из данного набора.

Minmax11. Дано целое число N и набор из N целых чисел. Найти номер последнего экстремального (т. е. минимального или максимального) элемента из данного набора.

Minmax12. Дано целое число N и набор из N чисел. Найти минимальное положительное число из данного набора. Если положительные числа в наборе отсутствуют, то вывести 0.

Minmax13. Дано целое число N и набор из N целых чисел. Найти номер первого максимального нечетного числа из данного набора. Если нечетные числа в наборе отсутствуют, то вывести 0.

Minmax14. Дано число B (> 0) и набор из десяти чисел. Вывести минимальный из тех элементов набора, которые больше B, а также его номер. Если чисел, больших B, в наборе нет, то дважды вывести 0.

Minmax15. Даны числа B, C (0 < B < C) и набор из десяти чисел. Вывести максимальный из элементов набора, содержащихся в интервале (B, C), и его номер. Если требуемые числа в наборе отсутствуют, то дважды вывести 0.

Minmax16. Дано целое число N и набор из N целых чисел. Найти количество элементов, расположенных перед первым минимальным элементом.

Minmax17. Дано целое число N и набор из N целых чисел. Найти количество элементов, расположенных после последнего максимального элемента.

Minmax18. Дано целое число N и набор из N целых чисел. Найти количество элементов, содержащихся между первым и последним максимальным элементом. Если в наборе имеется единственный максимальный элемент, то вывести 0.

Minmax19. Дано целое число N и набор из N целых чисел. Найти количество минимальных элементов из данного набора.

Minmax20. Дано целое число N и набор из N целых чисел. Найти общее количество экстремальных (т. е. минимальных и максимальных) элементов из данного набора.

Minmax21. Дано целое число N (> 2) и набор из N чисел — значений некоторой величины, полученных в N опытах. Найти среднее значение этой величины. При вычислении среднего значения не учитывать минимальное и максимальное из имеющихся в наборе значений.

Minmax22. Дано целое число N (> 2) и набор из N чисел. Найти два наименьших элемента из данного набора и вывести эти элементы в порядке возрастания их значений.

Minmax23. Дано целое число N (> 3) и набор из N чисел. Найти три наибольших элемента из данного набора и вывести эти элементы в порядке убывания их значений.

Minmax24. Дано целое число N (> 1) и набор из N чисел. Найти максимальную сумму двух соседних чисел из данного набора.

Minmax25. Дано целое число N (> 1) и набор из N чисел. Найти номера двух соседних чисел из данного набора, произведение которых является минимальным, и вывести вначале меньший, а затем больший номер.

Minmax26. Дано целое число N и набор из N целых чисел. Найти максимальное количество четных чисел в наборе, идущих подряд. Если четные числа в наборе отсутствуют, то вывести 0.

Minmax27. Дано целое число N и набор из N целых чисел, содержащий только нули и единицы. Найти номер элемента, с которого начинается самая длинная последовательность одинаковых чисел, и количество элементов в этой последовательности. Если таких последовательностей несколько, то вывести номер первой из них.

Minmax28. Дано целое число N и набор из N целых чисел, содержащий только нули и единицы. Найти номер элемента, с которого начинается самая длинная последовательность единиц, и количество элементов в этой последовательности. Если таких последовательностей несколько, то вывести номер последней из них. Если единицы в исходном наборе отсутствуют, то дважды вывести 0.


Группы заданий

Одномерные массивы: группа Array

[Перейти к указаниям для данной группы]

Условие вида «дан массив размера N» означает, что вначале дается фактический размер массива (целое число N), а затем приводятся все его элементы. Если в задании явно не указывается, какие значения может принимать размер исходного массива, то предполагается, что размер может изменяться в пределах от 2 до 10. Индекс начального элемента массива считается равным 1.

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

Одномерные массивы: формирование

При выполнении заданий на формирование массива можно считать, что размер результирующего массива не превосходит 10.

Array1. Дано целое число N (> 0). Сформировать и вывести целочисленный массив размера N, содержащий N первых положительных нечетных чисел: 1, 3, 5, … .

Array2. Дано целое число N (> 0). Сформировать и вывести целочисленный массив размера N, содержащий степени двойки от первой до N-й: 2, 4, 8, 16, … .

Array3. Дано целое число N (> 1), а также первый член A и разность D арифметической прогрессии. Сформировать и вывести массив размера N, содержащий N первых членов данной прогрессии:

A, A + D, A + 2·D, A + 3·D, … .

Array4. Дано целое число N (> 1), а также первый член A и знаменатель D геометрической прогрессии. Сформировать и вывести массив размера N, содержащий N первых членов данной прогрессии:

A, A·D, A·D2, A·D3, … .

Array5. Дано целое число N (> 2). Сформировать и вывести целочисленный массив размера N, содержащий N первых элементов последовательности чисел Фибоначчи FK:

F1 = 1, F2 = 1, FK = FK−2 + FK−1, K = 3, 4, … .

Array6. Даны целые числа N (> 2), A и B. Сформировать и вывести целочисленный массив размера N, первый элемент которого равен A, второй равен B, а каждый последующий элемент равен сумме всех предыдущих.

Одномерные массивы: вывод элементов

Array7. Дан массив размера N. Вывести его элементы в обратном порядке.

Array8. Дан целочисленный массив размера N. Вывести все содержащиеся в данном массиве нечетные числа в порядке возрастания их индексов, а также их количество K.

Array9. Дан целочисленный массив размера N. Вывести все содержащиеся в данном массиве четные числа в порядке убывания их индексов, а также их количество K.

Array10. Дан целочисленный массив размера N. Вывести вначале все содержащиеся в данном массиве четные числа в порядке возрастания их индексов, а затем — все нечетные числа в порядке убывания их индексов.

Array11. Дан массив A размера N и целое число K (1 ≤ K ≤ N). Вывести элементы массива с порядковыми номерами, кратными K: AK, A2·K, A3·K, … . Условный оператор не использовать.

Array12. Дан массив A размера N (N — четное число). Вывести его элементы с четными номерами в порядке возрастания номеров: A2, A4, A6, …, AN. Условный оператор не использовать.

Array13. Дан массив A размера N (N — нечетное число). Вывести его элементы с нечетными номерами в порядке убывания номеров: AN, AN−2, AN−4, …, A1. Условный оператор не использовать.

Array14. Дан массив A размера N. Вывести вначале его элементы с четными номерами (в порядке возрастания номеров), а затем — элементы с нечетными номерами (также в порядке возрастания номеров):

A2, A4, A6, …, A1, A3, A5, … .

Условный оператор не использовать.

Array15. Дан массив A размера N. Вывести вначале его элементы с нечетными номерами в порядке возрастания номеров, а затем — элементы с четными номерами в порядке убывания номеров:

A1, A3, A5, …, A6, A4, A2.

Условный оператор не использовать.

Array16. Дан массив A размера N. Вывести его элементы в следующем порядке:

A1, AN, A2, AN−1, A3, AN−2, … .

Array17. Дан массив A размера N. Вывести его элементы в следующем порядке:

A1, A2, AN, AN−1, A3, A4, AN−2, AN−3, … .

Одномерные массивы: анализ элементов

Для выполнения некоторых заданий, связанных с анализом элементов массива, не требуется одновременно хранить в памяти все исходные данные, поэтому использовать при их выполнении массивы, строго говоря, не нужно. Однако применение массивов позволяет сделать алгоритмы решения этих заданий более простыми и наглядными. Задания из данного пункта можно дополнить заданиями из групп «Последовательности» и «Минимумы и максимумы», рассматривая их как задания на обработку массивов. С другой стороны, для тех заданий данной группы, которые можно выполнить, не используя массивы, полезно реализовать и такие алгоритмы решения.

Array18. Дан массив A ненулевых целых чисел размера 10. Вывести значение первого из тех его элементов AK, которые удовлетворяют неравенству AK < A10. Если таких элементов нет, то вывести 0.

Array19. Дан целочисленный массив A размера 10. Вывести порядковый номер последнего из тех его элементов AK, которые удовлетворяют двойному неравенству A1 < AK < A10. Если таких элементов нет, то вывести 0.

Array20. Дан массив размера N и целые числа K и L (1 ≤ K ≤ L ≤ N). Найти сумму элементов массива с номерами от K до L включительно.

Array21. Дан массив размера N и целые числа K и L (1 ≤ K ≤ L ≤ N). Найти среднее арифметическое элементов массива с номерами от K до L включительно.

Array22. Дан массив размера N и целые числа K и L (1 < K ≤ L ≤ N). Найти сумму всех элементов массива, кроме элементов с номерами от K до L включительно.

Array23. Дан массив размера N и целые числа K и L (1 < K ≤ L ≤ N). Найти среднее арифметическое всех элементов массива, кроме элементов с номерами от K до L включительно.

Array24. Дан целочисленный массив размера N, не содержащий одинаковых чисел. Проверить, образуют ли его элементы арифметическую прогрессию (см. задание Array3). Если образуют, то вывести разность прогрессии, если нет — вывести 0.

Array25. Дан массив ненулевых целых чисел размера N. Проверить, образуют ли его элементы геометрическую прогрессию (см. задание Array4). Если образуют, то вывести знаменатель прогрессии, если нет — вывести 0.

Array26. Дан целочисленный массив размера N. Проверить, чередуются ли в нем четные и нечетные числа. Если чередуются, то вывести 0, если нет, то вывести порядковый номер первого элемента, нарушающего закономерность.

Array27. Дан массив ненулевых целых чисел размера N. Проверить, чередуются ли в нем положительные и отрицательные числа. Если чередуются, то вывести 0, если нет, то вывести порядковый номер первого элемента, нарушающего закономерность.

Array28. Дан массив A размера N. Найти минимальный элемент из его элементов с четными номерами: A2, A4, A6, … .

Array29. Дан массив A размера N. Найти максимальный элемент из его элементов с нечетными номерами: A1, A3, A5, … .

Array30. Дан массив размера N. Найти номера тех элементов массива, которые больше своего правого соседа, и количество таких элементов. Найденные номера выводить в порядке их возрастания.

Array31. Дан массив размера N. Найти номера тех элементов массива, которые больше своего левого соседа, и количество таких элементов. Найденные номера выводить в порядке их убывания.

Array32. Дан массив размера N. Найти номер его первого локального минимума (локальный минимум — это элемент, который меньше любого из своих соседей).

Array33. Дан массив размера N. Найти номер его последнего локального максимума (локальный максимум — это элемент, который больше любого из своих соседей).

Array34. Дан массив размера N. Найти максимальный из его локальных минимумов (определение локального минимума дано в задании Array32).

Array35. Дан массив размера N. Найти минимальный из его локальных максимумов (определение локального максимума дано в задании Array33).

Array36. Дан массив размера N. Найти максимальный из его элементов, не являющихся ни локальным минимумом, ни локальным максимумом (определения локального минимума и локального максимума даны в заданиях Array32 и Array33). Если таких элементов в массиве нет, то вывести 0 (как вещественное число).

Array37. Дан массив размера N. Найти количество участков, на которых его элементы возрастают.

Array38. Дан массив размера N. Найти количество участков, на которых его элементы убывают.

Array39. Дан массив размера N. Найти количество его промежутков монотонности (т. е. участков, на которых его элементы возрастают или убывают).

Array40. Дано число R и массив A размера N. Найти элемент массива, который наиболее близок к числу R (т. е. такой элемент AK, для которого величина |AK − R| является минимальной).

Array41. Дан массив размера N. Найти два соседних элемента, сумма которых максимальна, и вывести эти элементы в порядке возрастания их индексов.

Array42. Дано число R и массив размера N. Найти два соседних элемента массива, сумма которых наиболее близка к числу R, и вывести эти элементы в порядке возрастания их индексов (определение наиболее близких чисел дано в задании Array40).

Array43. Дан целочисленный массив размера N, все элементы которого упорядочены (по возрастанию или по убыванию). Найти количество различных элементов в данном массиве.

Array44. Дан целочисленный массив размера N, содержащий ровно два одинаковых элемента. Найти номера одинаковых элементов и вывести эти номера в порядке возрастания.

Array45. Дан массив размера N. Найти номера двух ближайших элементов из этого массива (т. е. элементов с наименьшим модулем разности) и вывести эти номера в порядке возрастания.

Array46. Дано число R и массив размера N. Найти два различных элемента массива, сумма которых наиболее близка к числу R, и вывести эти элементы в порядке возрастания их индексов (определение наиболее близких чисел дано в задании Array40).

Array47. Дан целочисленный массив размера N. Найти количество различных элементов в данном массиве.

Array48. Дан целочисленный массив размера N. Найти максимальное количество его одинаковых элементов.

Array49. Дан целочисленный массив размера N. Если он является перестановкой, т. е. содержит все числа от 1 до N, то вывести 0; в противном случае вывести номер первого недопустимого элемента.

Array50. Дан целочисленный массив A размера N, являющийся перестановкой (определение перестановки дано в задании Array49). Найти количество инверсий в данной перестановке, т. е. таких пар элементов AI и AJ, в которых большее число находится слева от меньшего: AI > AJ при I < J.

Работа с несколькими одномерными массивами

Array51. Даны массивы A и B одинакового размера N. Поменять местами их содержимое и вывести вначале элементы преобразованного массива A, а затем — элементы преобразованного массива B.

Array52. Дан массив A размера N. Сформировать новый массив B того же размера, элементы которого определяются следующим образом:

BK | = | 2·AK, | если AK < 5,
 |  | AK/2 | в противном случае.

Array53. Даны два массива A и B одинакового размера N. Сформировать новый массив C того же размера, каждый элемент которого равен максимальному из элементов массивов A и B с тем же индексом.

Array54. Дан целочисленный массив A размера N. Переписать в новый целочисленный массив B все четные числа из исходного массива (в том же порядке) и вывести размер полученного массива B и его содержимое.

Array55. Дан целочисленный массив A размера N (≤ 15). Переписать в новый целочисленный массив B все элементы с нечетными порядковыми номерами (1, 3, …) и вывести размер полученного массива B и его содержимое. Условный оператор не использовать.

Array56. Дан целочисленный массив A размера N (≤ 15). Переписать в новый целочисленный массив B все элементы с порядковыми номерами, кратными трем (3, 6, …), и вывести размер полученного массива B и его содержимое. Условный оператор не использовать.

Array57. Дан целочисленный массив A размера N. Переписать в новый целочисленный массив B того же размера вначале все элементы исходного массива с четными номерами, а затем — с нечетными:

A2, A4, A6, …, A1, A3, A5, … .

Условный оператор не использовать.

Array58. Дан массив A размера N. Сформировать новый массив B того же размера по следующему правилу: элемент BK равен сумме элементов массива A с номерами от 1 до K.

Array59. Дан массив A размера N. Сформировать новый массив B того же размера по следующему правилу: элемент BK равен среднему арифметическому элементов массива A с номерами от 1 до K.

Array60. Дан массив A размера N. Сформировать новый массив B того же размера по следующему правилу: элемент BK равен сумме элементов массива A с номерами от K до N.

Array61. Дан массив A размера N. Сформировать новый массив B того же размера по следующему правилу: элемент BK равен среднему арифметическому элементов массива A с номерами от K до N.

Array62. Дан массив A размера N. Сформировать два новых массива B и C: в массив B записать все положительные элементы массива A, в массив C — все отрицательные (сохраняя исходный порядок следования элементов). Вывести вначале размер и содержимое массива B, а затем — размер и содержимое массива C.

Array63. Даны два массива A и B размера 5, элементы которых упорядочены по возрастанию. Объединить эти массивы так, чтобы результирующий массив C (размера 10) остался упорядоченным по возрастанию.

Array64. Даны три целочисленных массива A, B и C размера NA, NB, NC соответственно, элементы которых упорядочены по убыванию. Объединить эти массивы так, чтобы результирующий целочисленный массив D (размера NA + NB + NC) остался упорядоченным по убыванию.

Одномерные массивы: преобразование

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

Array65. Дан массив A размера N и целое число K (1 ≤ K ≤ N). Преобразовать массив, увеличив каждый его элемент на исходное значение элемента AK.

Array66. Дан целочисленный массив размера N. Увеличить все четные числа, содержащиеся в массиве, на исходное значение первого четного числа. Если четные числа в массиве отсутствуют, то оставить массив без изменений.

Array67. Дан целочисленный массив размера N. Увеличить все нечетные числа, содержащиеся в массиве, на исходное значение последнего нечетного числа. Если нечетные числа в массиве отсутствуют, то оставить массив без изменений.

Array68. Дан массив размера N. Поменять местами его минимальный и максимальный элементы.

Array69. Дан массив размера N (N — четное число). Поменять местами его первый элемент со вторым, третий — с четвертым и т. д.

Array70. Дан массив размера N (N — четное число). Поменять местами первую и вторую половины массива.

Array71. Дан массив размера N. Поменять порядок его элементов на обратный.

Array72. Дан массив A размера N и целые числа K и L (1 ≤ K < L ≤ N). Переставить в обратном порядке элементы массива, расположенные между элементами AK и AL, включая эти элементы.

Array73. Дан массив A размера N и целые числа K и L (1 ≤ K < L ≤ N). Переставить в обратном порядке элементы массива, расположенные между элементами AK и AL, не включая эти элементы.

Array74. Дан массив размера N. Обнулить элементы массива, расположенные между его минимальным и максимальным элементами (не включая минимальный и максимальный элементы).

Array75. Дан массив размера N. Переставить в обратном порядке элементы массива, расположенные между его минимальным и максимальным элементами, включая минимальный и максимальный элементы.

Array76. Дан массив размера N. Обнулить все его локальные максимумы (т. е. числа, большие своих соседей).

Array77. Дан массив размера N. Возвести в квадрат все его локальные минимумы (т. е. числа, меньшие своих соседей).

Array78. Дан массив размера N. Заменить каждый элемент массива на среднее арифметическое этого элемента и его соседей.

Array79. Дан массив размера N. Осуществить сдвиг элементов массива вправо на одну позицию (при этом A1 перейдет в A2, A2 — в A3, …, AN−1 — в AN, a исходное значение последнего элемента будет потеряно). Первый элемент полученного массива положить равным 0.

Array80. Дан массив размера N. Осуществить сдвиг элементов массива влево на одну позицию (при этом AN перейдет в AN−1, AN−1 — в AN−2, …, A2 — в A1, a исходное значение первого элемента будет потеряно). Последний элемент полученного массива положить равным 0.

Array81. Дан массив размера N и целое число K (1 ≤ K < N). Осуществить сдвиг элементов массива вправо на K позиций (при этом A1 перейдет в AK+1, A2 — в AK+2, …, AN−K — в AN, а исходное значение K последних элементов будет потеряно). Первые K элементов полученного массива положить равными 0.

Array82. Дан массив размера N и целое число K (1 ≤ K < N). Осуществить сдвиг элементов массива влево на K позиций (при этом AN перейдет в AN−K, AN−1 — в AN−K−1, …, AK+1 — в A1, а исходное значение K первых элементов будет потеряно). Последние K элементов полученного массива положить равными 0.

Array83. Дан массив размера N. Осуществить циклический сдвиг элементов массива вправо на одну позицию (при этом A1 перейдет в A2, A2 — в A3, …, AN — в A1).

Array84. Дан массив размера N. Осуществить циклический сдвиг элементов массива влево на одну позицию (при этом AN перейдет в AN−1, AN−1 — в AN−2, …, A1 — в AN).

Array85. Дан массив A размера N и целое число K (1 ≤ K ≤ 4, K < N). Осуществить циклический сдвиг элементов массива вправо на K позиций (при этом A1 перейдет в AK+1, A2 — в AK+2, …, AN — в AK). Допускается использовать вспомогательный массив из 4 элементов.

Array86. Дан массив A размера N и целое число K (1 ≤ K ≤ 4, K < N). Осуществить циклический сдвиг элементов массива влево на K позиций (при этом AN перейдет в AN−K, AN−1 — в AN−K−1, …, A1 — в AN−K+1). Допускается использовать вспомогательный массив из 4 элементов.

Array87. Дан массив размера N, все элементы которого, кроме первого, упорядочены по возрастанию. Сделать массив упорядоченным, переместив первый элемент на новую позицию.

Array88. Дан массив размера N, все элементы которого, кроме последнего, упорядочены по возрастанию. Сделать массив упорядоченным, переместив последний элемент на новую позицию.

Array89. Дан массив размера N, все элементы которого, кроме одного, упорядочены по убыванию. Сделать массив упорядоченным, переместив элемент, нарушающий упорядоченность, на новую позицию.

Array90. Дан массив размера N и целое число K (1 ≤ K ≤ N). Удалить из массива элемент с порядковым номером K.

Array91. Дан массив размера N и целые числа K и L (1 ≤ K < L ≤ N). Удалить из массива элементы с номерами от K до L включительно и вывести размер полученного массива и его содержимое.

Array92. Дан целочисленный массив размера N. Удалить из массива все нечетные числа и вывести размер полученного массива и его содержимое.

Array93. Дан целочисленный массив размера N (> 2). Удалить из массива все элементы с четными номерами (2, 4, …). Условный оператор не использовать.

Array94. Дан целочисленный массив размера N (> 2). Удалить из массива все элементы с нечетными номерами (1, 3, …). Условный оператор не использовать.

Array95. Дан целочисленный массив размера N. Удалить из массива все соседние одинаковые элементы, оставив их первые вхождения.

Array96. Дан целочисленный массив размера N. Удалить из массива все одинаковые элементы, оставив их первые вхождения.

Array97. Дан целочисленный массив размера N. Удалить из массива все одинаковые элементы, оставив их последние вхождения.

Array98. Дан целочисленный массив размера N. Удалить из массива все элементы, встречающиеся менее трех раз, и вывести размер полученного массива и его содержимое.

Array99. Дан целочисленный массив размера N. Удалить из массива все элементы, встречающиеся более двух раз, и вывести размер полученного массива и его содержимое.

Array100. Дан целочисленный массив размера N. Удалить из массива все элементы, встречающиеся ровно два раза, и вывести размер полученного массива и его содержимое.

Array101. Дан массив размера N и целое число K (1 ≤ K ≤ N). Перед элементом массива с порядковым номером K вставить новый элемент с нулевым значением.

Array102. Дан массив размера N и целое число K (1 ≤ K ≤ N). После элемента массива с порядковым номером K вставить новый элемент с нулевым значением.

Array103. Дан массив размера N. Вставить элемент с нулевым значением перед минимальным и после максимального элемента массива.

Array104. Дан массив размера N и два целых числа K и M (1 ≤ K ≤ N, 1 ≤ M ≤ 10). Перед элементом массива с номером K вставить M новых элементов с нулевыми значениями.

Array105. Дан массив размера N и два целых числа K и M (1 ≤ K ≤ N, 1 ≤ M ≤ 10). После элемента массива с номером K вставить M новых элементов с нулевыми значениями.

Array106. Дан массив размера N. Продублировать в нем элементы с четными номерами (2, 4, …). Условный оператор в цикле не использовать.

Array107. Дан массив размера N. Утроить в нем вхождения всех элементов с нечетными номерами (1, 3, …). Условный оператор в цикле не использовать.

Array108. Дан массив размера N. Перед каждым положительным элементом массива вставить элемент с нулевым значением.

Array109. Дан массив размера N. После каждого отрицательного элемента массива вставить элемент с нулевым значением.

Array110. Дан целочисленный массив размера N. Продублировать в нем все четные числа.

Array111. Дан целочисленный массив размера N. Утроить в нем вхождения всех нечетных чисел.

Array112. Дан массив A размера N (≤ 6). Упорядочить его по возрастанию методом сортировки простым обменом («пузырьковой» сортировкой): просматривать массив, сравнивая его соседние элементы (A1 и A2, A2 и A3 и т. д.) и меняя их местами, если левый элемент пары больше правого; повторить описанные действия N − 1 раз. Для контроля за выполняемыми действиями выводить содержимое массива после каждого просмотра. Учесть, что при каждом просмотре количество анализируемых пар можно уменьшить на 1.

Array113. Дан массив A размера N (≤ 6). Упорядочить его по возрастанию методом сортировки простым выбором: найти максимальный элемент массива и поменять его местами с последним (N-м) элементом; выполнить описанные действия N − 1 раз, каждый раз уменьшая на 1 количество анализируемых элементов и выводя содержимое массива.

Array114. Дан массив A размера N (≤ 6). Упорядочить его по возрастанию методом сортировки простыми вставками: сравнить элементы A1 и A2 и, при необходимости меняя их местами, добиться того, чтобы они оказались упорядоченными по возрастанию; затем обратиться к элементу A3 и переместить его в левую (уже упорядоченную) часть массива, сохранив ее упорядоченность; повторить этот процесс для остальных элементов, выводя содержимое массива после обработки каждого элемента (от 2-го до N-го). При выполнении описанных действий удобно использовать прием «барьера», записывая очередной элемент перед его обработкой в дополнительный элемент массива A0.

Array115. Дан массив A размера N. Не изменяя данный массив, вывести номера его элементов в том порядке, в котором соответствующие им элементы образуют возрастающую последовательность. Использовать метод «пузырьковой» сортировки (см. задание Array112), модифицировав его следующим образом: создать вспомогательный целочисленный массив номеров I, заполнив его числами от 1 до N; просматривать массив A, сравнивая пары элементов массива A с номерами I1 и I2, I2 и I3, … и меняя местами соответствующие элементы массива I, если левый элемент пары больше правого. Повторив описанную процедуру просмотра N − 1 раз, получим в массиве I требуемую последовательность номеров.

Одномерные массивы: серии целых чисел

Array116. Дан целочисленный массив A размера N. Назовем серией группу подряд идущих одинаковых элементов, а длиной серии — количество этих элементов (длина серии может быть равна 1). Сформировать два новых целочисленных массива B и C одинакового размера, записав в массив B длины всех серий исходного массива, а в массив C — значения элементов, образующих эти серии.

Array117. Дан целочисленный массив размера N. Вставить перед каждой его серией элемент с нулевым значением (определение серии дано в задании Array116).

Array118. Дан целочисленный массив размера N. Вставить после каждой его серии элемент с нулевым значением (определение серии дано в задании Array116).

Array119. Дан целочисленный массив размера N. Преобразовать массив, увеличив каждую его серию на один элемент (определение серии дано в задании Array116).

Array120. Дан целочисленный массив размера N, содержащий по крайней мере одну серию, длина которой больше 1. Преобразовать массив, уменьшив каждую его серию на один элемент (определение серии дано в задании Array116).

Array121. Дано целое число K (> 0) и целочисленный массив размера N. Преобразовать массив, удвоив длину его серии с номером K (определение серии дано в задании Array116). Если серий в массиве меньше K, то вывести массив без изменений.

Array122. Дано целое число K (> 1) и целочисленный массив размера N. Удалить из массива серию с номером K (определение серии дано в задании Array116). Если серий в массиве меньше K, то вывести массив без изменений.

Array123. Дано целое число K (> 1) и целочисленный массив размера N. Поменять местами первую серию массива и его серию с номером K (определение серии дано в задании Array116). Если серий в массиве меньше K, то вывести массив без изменений.

Array124. Дано целое число K (> 0) и целочисленный массив размера N. Поменять местами последнюю серию массива и его серию с номером K (определение серии дано в задании Array116). Если серий в массиве меньше K, то вывести массив без изменений.

Array125. Дано целое число L (> 1) и целочисленный массив размера N. Заменить каждую серию массива, длина которой меньше L, на один элемент с нулевым значением (определение серии дано в задании Array116).

Array126. Дано целое число L (> 0) и целочисленный массив размера N. Заменить каждую серию массива, длина которой равна L, на один элемент с нулевым значением (определение серии дано в задании Array116).

Array127. Дано целое число L (> 0) и целочисленный массив размера N. Заменить каждую серию массива, длина которой больше L, на один элемент с нулевым значением (определение серии дано в задании Array116).

Array128. Дан целочисленный массив размера N. Преобразовать массив, увеличив его первую серию наибольшей длины на один элемент (определение серии дано в задании Array116).

Array129. Дан целочисленный массив размера N. Преобразовать массив, увеличив его последнюю серию наибольшей длины на один элемент (определение серии дано в задании Array116).

Array130. Дан целочисленный массив размера N. Преобразовать массив, увеличив все его серии наибольшей длины на один элемент (определение серии дано в задании Array116).

Одномерные массивы: множества точек на плоскости

Для хранения данных о каждом наборе точек следует использовать по два массива: первый массив для хранения абсцисс, второй — для хранения ординат. Можно также использовать массив записей с двумя полями.

Array131. Дано множество A из N точек на плоскости и точка B (точки заданы своими координатами x, y). Найти точку из множества A, наиболее близкую к точке B. Расстояние R между точками с координатами (x1, y1) и (x2, y2) вычисляется по формуле:

R = ((x2 − x1)2 + (y2 − y1)2)1/2.

Array132. Дано множество A из N точек (точки заданы своими координатами x, y). Среди всех точек этого множества, лежащих во второй четверти, найти точку, наиболее удаленную от начала координат. Если таких точек нет, то вывести точку с нулевыми координатами.

Array133. Дано множество A из N точек (точки заданы своими координатами x, y). Среди всех точек этого множества, лежащих в первой или третьей четверти, найти точку, наиболее близкую к началу координат. Если таких точек нет, то вывести точку с нулевыми координатами.

Array134. Дано множество A из N точек (точки заданы своими координатами x, y). Найти пару точек этого множества с максимальным расстоянием между ними и само это расстояние (точки выводятся в том же порядке, в котором они перечислены при задании множества A).

Array135. Даны множества A и B, состоящие соответственно из N1 и N2 точек (точки заданы своими координатами x, y). Найти минимальное расстояние между точками этих множеств и сами точки, расположенные на этом расстоянии (вначале выводится точка из множества A, затем точка из множества B).

Array136. Дано множество A из N точек (N > 2, точки заданы своими координатами x, y). Найти такую точку из данного множества, сумма расстояний от которой до остальных его точек минимальна, и саму эту сумму.

Array137. Дано множество A из N точек (N > 2, точки заданы своими координатами x, y). Найти наибольший периметр треугольника, вершины которого принадлежат различным точкам множества A, и сами эти точки (точки выводятся в том же порядке, в котором они перечислены при задании множества A).

Array138. Дано множество A из N точек (N > 2, точки заданы своими координатами x, y). Найти наименьший периметр треугольника, вершины которого принадлежат различным точкам множества A, и сами эти точки (точки выводятся в том же порядке, в котором они перечислены при задании множества A).

Array139. Дано множество A из N точек с целочисленными координатами x, y. Порядок на координатной плоскости определим следующим образом:

(x1, y1) < (x2, y2), если либо x1 < x2, либо x1 = x2 и y1 < y2.

Расположить точки данного множества по возрастанию в соответствии с указанным порядком.

Array140. Дано множество A из N точек с целочисленными координатами x, y. Порядок на координатной плоскости определим следующим образом:

(x1, y1) < (x2, y2), если либо x1 + y1 < x2 + y2, либо x1 + y1 = x2 + y2 и x1 < x2.

Расположить точки данного множества по убыванию в соответствии с указанным порядком.


Группы заданий

Двумерные массивы (матрицы): группа Matrix

Условие вида «дана матрица размера M × N» означает, что вначале дается фактический размер двумерного массива-матрицы (количество строк M и количество столбцов N), а затем приводятся элементы этого массива (количество элементов равно M·N). Если в задании явно не указывается, какие значения могут принимать размеры исходной матрицы, то предполагается, что и число строк, и число столбцов может изменяться в пределах от 2 до 10. Начальные значения как первого, так и второго индекса двумерного массива-матрицы всегда считаются равными 1. Ввод и вывод элементов матрицы осуществляются по строкам.

Квадратной матрицей порядка M называется двумерный массив-матрица размера M × M.

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

Двумерные массивы (матрицы): формирование

При выполнении заданий на формирование матриц можно считать, что размер результирующей матрицы не превосходит 10 × 10.

Matrix1. Даны целые положительные числа M и N. Сформировать целочисленную матрицу размера M × N, у которой все элементы I-й строки имеют значение 10·I (I = 1, …, M).

Matrix2. Даны целые положительные числа M и N. Сформировать целочисленную матрицу размера M × N, у которой все элементы J-го столбца имеют значение 5·J (J = 1, …, N).

Matrix3. Даны целые положительные числа M, N и набор из M чисел. Сформировать матрицу размера M × N, у которой в каждом столбце содержатся все числа из исходного набора (в том же порядке).

Matrix4. Даны целые положительные числа M, N и набор из N чисел. Сформировать матрицу размера M × N, у которой в каждой строке содержатся все числа из исходного набора (в том же порядке).

Matrix5. Даны целые положительные числа M, N, число D и набор из M чисел. Сформировать матрицу размера M × N, у которой первый столбец совпадает с исходным набором чисел, а элементы каждого следующего столбца равны сумме соответствующего элемента предыдущего столбца и числа D (в результате каждая строка матрицы будет содержать элементы арифметической прогрессии).

Matrix6. Даны целые положительные числа M, N, число D и набор из N чисел. Сформировать матрицу размера M × N, у которой первая строка совпадает с исходным набором чисел, а элементы каждой следующей строки равны соответствующему элементу предыдущей строки, умноженному на D (в результате каждый столбец матрицы будет содержать элементы геометрической прогрессии).

Двумерные массивы (матрицы): вывод элементов

Matrix7. Дана матрица размера M × N и целое число K (1 ≤ K ≤ M). Вывести элементы K-й строки данной матрицы.

Matrix8. Дана матрица размера M × N и целое число K (1 ≤ K ≤ N). Вывести элементы K-го столбца данной матрицы.

Matrix9. Дана матрица размера M × N. Вывести ее элементы, расположенные в строках с четными номерами (2, 4, …). Вывод элементов производить по строкам, условный оператор не использовать.

Matrix10. Дана матрица размера M × N. Вывести ее элементы, расположенные в столбцах с нечетными номерами (1, 3, …). Вывод элементов производить по столбцам, условный оператор не использовать.

Matrix11. Дана матрица размера M × N. Вывести ее элементы в следующем порядке: первая строка слева направо, вторая строка справа налево, третья строка слева направо, четвертая строка справа налево и т. д.

Matrix12. Дана матрица размера M × N. Вывести ее элементы в следующем порядке: первый столбец сверху вниз, второй столбец снизу вверх, третий столбец сверху вниз, четвертый столбец снизу вверх и т. д.

Matrix13. Дана квадратная матрица A порядка M. Начиная с элемента A1,1, вывести ее элементы следующим образом («уголками»): все элементы первой строки; элементы последнего столбца, кроме первого (уже выведенного) элемента; оставшиеся элементы второй строки; оставшиеся элементы предпоследнего столбца и т. д.; последним выводится элемент AM,1.

Matrix14. Дана квадратная матрица A порядка M. Начиная с элемента A1,1, вывести ее элементы следующим образом («уголками»): все элементы первого столбца; элементы последней строки, кроме первого (уже выведенного) элемента; оставшиеся элементы второго столбца; оставшиеся элементы предпоследней строки и т. д.; последним выводится элемент A1,M.

Matrix15. Дана квадратная матрица A порядка M (M — нечетное число). Начиная с элемента A1,1 и перемещаясь по часовой стрелке, вывести все ее элементы по спирали: первая строка, последний столбец, последняя строка в обратном порядке, первый столбец в обратном порядке, оставшиеся элементы второй строки и т. д.; последним выводится центральный элемент матрицы.

Matrix16. Дана квадратная матрица A порядка M (M — нечетное число). Начиная с элемента A1,1 и перемещаясь против часовой стрелки, вывести все ее элементы по спирали: первый столбец, последняя строка, последний столбец в обратном порядке, первая строка в обратном порядке, оставшиеся элементы второго столбца и т. д.; последним выводится центральный элемент матрицы.

Двумерные массивы (матрицы): анализ элементов

Matrix17. Дана матрица размера M × N и целое число K (1 ≤ K ≤ M). Найти сумму и произведение элементов K-й строки данной матрицы.

Matrix18. Дана матрица размера M × N и целое число K (1 ≤ K ≤ N). Найти сумму и произведение элементов K-го столбца данной матрицы.

Matrix19. Дана матрица размера M × N. Для каждой строки матрицы найти сумму ее элементов.

Matrix20. Дана матрица размера M × N. Для каждого столбца матрицы найти произведение его элементов.

Matrix21. Дана матрица размера M × N. Для каждой строки матрицы с нечетным номером (1, 3, …) найти среднее арифметическое ее элементов. Условный оператор не использовать.

Matrix22. Дана матрица размера M × N. Для каждого столбца матрицы с четным номером (2, 4, …) найти сумму его элементов. Условный оператор не использовать.

Matrix23. Дана матрица размера M × N. В каждой строке матрицы найти минимальный элемент.

Matrix24. Дана матрица размера M × N. В каждом столбце матрицы найти максимальный элемент.

Matrix25. Дана матрица размера M × N. Найти номер ее строки с наибольшей суммой элементов и вывести данный номер, а также значение наибольшей суммы.

Matrix26. Дана матрица размера M × N. Найти номер ее столбца с наименьшим произведением элементов и вывести данный номер, а также значение наименьшего произведения.

Matrix27. Дана матрица размера M × N. Найти максимальный среди минимальных элементов ее строк.

Matrix28. Дана матрица размера M × N. Найти минимальный среди максимальных элементов ее столбцов.

Matrix29. Дана матрица размера M × N. В каждой ее строке найти количество элементов, меньших среднего арифметического всех элементов этой строки.

Matrix30. Дана матрица размера M × N. В каждом ее столбце найти количество элементов, больших среднего арифметического всех элементов этого столбца.

Matrix31. Дана матрица размера M × N. Найти номера строки и столбца для элемента матрицы, наиболее близкого к среднему значению всех ее элементов.

Matrix32. Дана целочисленная матрица размера M × N. Найти номер первой из ее строк, содержащих равное количество положительных и отрицательных элементов (нулевые элементы матрицы не учитываются). Если таких строк нет, то вывести 0.

Matrix33. Дана целочисленная матрица размера M × N. Найти номер последнего из ее столбцов, содержащих равное количество положительных и отрицательных элементов (нулевые элементы матрицы не учитываются). Если таких столбцов нет, то вывести 0.

Matrix34. Дана целочисленная матрица размера M × N. Найти номер последней из ее строк, содержащих только четные числа. Если таких строк нет, то вывести 0.

Matrix35. Дана целочисленная матрица размера M × N. Найти номер первого из ее столбцов, содержащих только нечетные числа. Если таких столбцов нет, то вывести 0.

Matrix36. Дана целочисленная матрица размера M × N, элементы которой могут принимать значения от 0 до 100. Различные строки матрицы назовем похожими, если совпадают множества чисел, встречающихся в этих строках. Найти количество строк, похожих на первую строку данной матрицы.

Matrix37. Дана целочисленная матрица размера M × N, элементы которой могут принимать значения от 0 до 100. Различные столбцы матрицы назовем похожими, если совпадают множества чисел, встречающихся в этих столбцах. Найти количество столбцов, похожих на последний столбец данной матрицы.

Matrix38. Дана целочисленная матрица размера M × N. Найти количество ее строк, все элементы которых различны.

Matrix39. Дана целочисленная матрица размера M × N. Найти количество ее столбцов, все элементы которых различны.

Matrix40. Дана целочисленная матрица размера M × N. Найти номер последней из ее строк, содержащих максимальное количество одинаковых элементов.

Matrix41. Дана целочисленная матрица размера M × N. Найти номер первого из ее столбцов, содержащих максимальное количество одинаковых элементов.

Matrix42. Дана матрица размера M × N. Найти количество ее строк, элементы которых упорядочены по возрастанию.

Matrix43. Дана матрица размера M × N. Найти количество ее столбцов, элементы которых упорядочены по убыванию.

Matrix44. Дана матрица размера M × N. Найти минимальный среди элементов тех строк, которые упорядочены либо по возрастанию, либо по убыванию. Если упорядоченные строки в матрице отсутствуют, то вывести 0.

Matrix45. Дана матрица размера M × N. Найти максимальный среди элементов тех столбцов, которые упорядочены либо по возрастанию, либо по убыванию. Если упорядоченные столбцы в матрице отсутствуют, то вывести 0.

Matrix46. Дана целочисленная матрица размера M × N. Найти элемент, являющийся максимальным в своей строке и минимальным в своем столбце. Если такой элемент отсутствует, то вывести 0.

Двумерные массивы (матрицы): преобразование

При выполнении заданий на преобразование матриц не следует использовать вспомогательные двумерные массивы-матрицы, за исключением тех заданий, в которых явно сказано о допустимости применения вспомогательных матриц.

Matrix47. Дана матрица размера M × N и целые числа K1 и K2 (1 ≤ K1 < K2 ≤ M). Поменять местами строки матрицы с номерами K1 и K2.

Matrix48. Дана матрица размера M × N и целые числа K1 и K2 (1 ≤ K1 < K2 ≤ N). Поменять местами столбцы матрицы с номерами K1 и K2.

Matrix49. Дана матрица размера M × N. Преобразовать матрицу, поменяв местами минимальный и максимальный элемент в каждой строке.

Matrix50. Дана матрица размера M × N. Преобразовать матрицу, поменяв местами минимальный и максимальный элемент в каждом столбце.

Matrix51. Дана матрица размера M × N. Поменять местами строки, содержащие минимальный и максимальный элементы матрицы.

Matrix52. Дана матрица размера M × N. Поменять местами столбцы, содержащие минимальный и максимальный элементы матрицы.

Matrix53. Дана матрица размера M × N. Поменять местами столбец с номером 1 и последний из столбцов, содержащих только положительные элементы. Если требуемых столбцов нет, то вывести матрицу без изменений.

Matrix54. Дана матрица размера M × N. Поменять местами столбец с номером N и первый из столбцов, содержащих только отрицательные элементы. Если требуемых столбцов нет, то вывести матрицу без изменений.

Matrix55. Дана матрица размера M × N (M — четное число). Поменять местами верхнюю и нижнюю половины матрицы.

Matrix56. Дана матрица размера M × N (N — четное число). Поменять местами левую и правую половины матрицы.

Matrix57. Дана матрица размера M × N (M и N — четные числа). Поменять местами левую верхнюю и правую нижнюю четверти матрицы.

Matrix58. Дана матрица размера M × N (M и N — четные числа). Поменять местами левую нижнюю и правую верхнюю четверти матрицы.

Matrix59. Дана матрица размера M × N. Зеркально отразить ее элементы относительно горизонтальной оси симметрии матрицы (при этом поменяются местами строки с номерами 1 и M, 2 и M − 1 и т. д.).

Matrix60. Дана матрица размера M × N. Зеркально отразить ее элементы относительно вертикальной оси симметрии матрицы (при этом поменяются местами столбцы с номерами 1 и N, 2 и N − 1 и т. д.).

Matrix61. Дана матрица размера M × N и целое число K (1 ≤ K ≤ M). Удалить строку матрицы с номером K.

Matrix62. Дана матрица размера M × N и целое число K (1 ≤ K ≤ N). Удалить столбец матрицы с номером K.

Matrix63. Дана матрица размера M × N. Удалить строку, содержащую минимальный элемент матрицы.

Matrix64. Дана матрица размера M × N. Удалить столбец, содержащий максимальный элемент матрицы.

Matrix65. Дана матрица размера M × N. Удалить ее первый столбец, содержащий только положительные элементы. Если требуемых столбцов нет, то вывести матрицу без изменений.

Matrix66. Дана матрица размера M × N. Удалить ее последний столбец, содержащий только отрицательные элементы. Если требуемых столбцов нет, то вывести матрицу без изменений.

Matrix67. Дана матрица размера M × N, содержащая как положительные, так и отрицательные элементы. Удалить все ее столбцы, содержащие только положительные элементы. Если требуемых столбцов нет, то вывести матрицу без изменений.

Matrix68. Дана матрица размера M × N и целое число K (1 ≤ K ≤ M). Перед строкой матрицы с номером K вставить строку из нулей.

Matrix69. Дана матрица размера M × N и целое число K (1 ≤ K ≤ N). После столбца матрицы с номером K вставить столбец из единиц.

Matrix70. Дана матрица размера M × N. Продублировать строку матрицы, содержащую ее максимальный элемент.

Matrix71. Дана матрица размера M × N. Продублировать столбец матрицы, содержащий ее минимальный элемент.

Matrix72. Дана матрица размера M × N. Перед первым столбцом, содержащим только положительные элементы, вставить столбец из единиц. Если требуемых столбцов нет, то вывести матрицу без изменений.

Matrix73. Дана матрица размера M × N. После последнего столбца, содержащего только отрицательные элементы, вставить столбец из нулей. Если требуемых столбцов нет, то вывести матрицу без изменений.

Matrix74. Дана матрица размера M × N. Элемент матрицы называется ее локальным минимумом, если он меньше всех окружающих его элементов. Заменить все локальные минимумы данной матрицы на нули. При решении допускается использовать вспомогательную матрицу.

Matrix75. Дана матрица размера M × N. Элемент матрицы называется ее локальным максимумом, если он больше всех окружающих его элементов. Поменять знак всех локальных максимумов данной матрицы на противоположный. При решении допускается использовать вспомогательную матрицу.

Matrix76. Дана матрица размера M × N. Упорядочить ее строки так, чтобы их первые элементы образовывали возрастающую последовательность.

Matrix77. Дана матрица размера M × N. Упорядочить ее столбцы так, чтобы их последние элементы образовывали убывающую последовательность.

Matrix78. Дана матрица размера M × N. Упорядочить ее строки так, чтобы их минимальные элементы образовывали убывающую последовательность.

Matrix79. Дана матрица размера M × N. Упорядочить ее столбцы так, чтобы их максимальные элементы образовывали возрастающую последовательность.

Двумерные массивы (матрицы): работа с диагоналями

Matrix80. Дана квадратная матрица A порядка M. Найти сумму элементов ее главной диагонали, т. е. диагонали, содержащей следующие элементы:

A1,1, A2,2, A3,3, …, AM,M.

Matrix81. Дана квадратная матрица A порядка M. Найти среднее арифметическое элементов ее побочной диагонали, т. е. диагонали, содержащей следующие элементы:

A1,M, A2,M−1, A3,M−2, …, AM,1.

Matrix82. Дана квадратная матрица A порядка M. Найти сумму элементов каждой ее диагонали, параллельной главной (начиная с одноэлементной диагонали A1,M).

Matrix83. Дана квадратная матрица A порядка M. Найти сумму элементов каждой ее диагонали, параллельной побочной (начиная с одноэлементной диагонали A1,1).

Matrix84. Дана квадратная матрица A порядка M. Найти среднее арифметическое элементов каждой ее диагонали, параллельной главной (начиная с одноэлементной диагонали A1,M).

Matrix85. Дана квадратная матрица A порядка M. Найти среднее арифметическое элементов каждой ее диагонали, параллельной побочной (начиная с одноэлементной диагонали A1,1).

Matrix86. Дана квадратная матрица A порядка M. Найти минимальный элемент для каждой ее диагонали, параллельной главной (начиная с одноэлементной диагонали A1,M).

Matrix87. Дана квадратная матрица A порядка M. Найти максимальный элемент для каждой ее диагонали, параллельной побочной (начиная с одноэлементной диагонали A1,1).

Matrix88. Дана квадратная матрица порядка M. Обнулить элементы матрицы, лежащие ниже главной диагонали. Условный оператор не использовать.

Matrix89. Дана квадратная матрица порядка M. Обнулить элементы матрицы, лежащие выше побочной диагонали. Условный оператор не использовать.

Matrix90. Дана квадратная матрица порядка M. Обнулить элементы матрицы, лежащие на побочной диагонали и ниже нее. Условный оператор не использовать.

Matrix91. Дана квадратная матрица порядка M. Обнулить элементы матрицы, лежащие на главной диагонали и выше нее. Условный оператор не использовать.

Matrix92. Дана квадратная матрица порядка M. Обнулить элементы матрицы, лежащие одновременно выше главной диагонали и выше побочной диагонали. Условный оператор не использовать.

Matrix93. Дана квадратная матрица порядка M. Обнулить элементы матрицы, лежащие одновременно выше главной диагонали и ниже побочной диагонали. Условный оператор не использовать.

Matrix94. Дана квадратная матрица порядка M. Обнулить элементы матрицы, лежащие одновременно ниже главной диагонали (включая эту диагональ) и выше побочной диагонали (также включая эту диагональ). Условный оператор не использовать.

Matrix95. Дана квадратная матрица порядка M. Обнулить элементы матрицы, лежащие одновременно ниже главной диагонали (включая эту диагональ) и ниже побочной диагонали (также включая эту диагональ). Условный оператор не использовать.

Matrix96. Дана квадратная матрица A порядка M. Зеркально отразить ее элементы относительно главной диагонали (при этом элементы главной диагонали останутся на прежнем месте, элемент A1,2 поменяется местами с A2,1, элемент A1,3 — с A3,1 и т. д.). Вспомогательную матрицу не использовать.

Matrix97. Дана квадратная матрица A порядка M. Зеркально отразить ее элементы относительно побочной диагонали (при этом элементы побочной диагонали останутся на прежнем месте, элемент A1,1 поменяется местами с AM,M, элемент A1,2 — с AM−1,M и т. д.). Вспомогательную матрицу не использовать.

Matrix98. Дана квадратная матрица A порядка M. Повернуть ее на угол 180° (при этом элемент A1,1 поменяется местами с AM,M, элемент A1,2 — с AM,M−1 и т. д.). Вспомогательную матрицу не использовать.

Matrix99. Дана квадратная матрица A порядка M. Повернуть ее на угол 90° в положительном направлении, т. е. против часовой стрелки (при этом элемент A1,1 перейдет в AM,1, элемент AM,1 — в AM,M и т. д.). Вспомогательную матрицу не использовать.

Matrix100. Дана квадратная матрица A порядка M. Повернуть ее на угол 90° в отрицательном направлении, т. е. по часовой стрелке (при этом элемент A1,1 перейдет в A1,M, элемент A1,M — в AM,M и т. д.). Вспомогательную матрицу не использовать.


Группы заданий

Символы и строки: группа String

При выполнении заданий на обработку русских букв можно считать, что буква «ё» в исходных строковых данных отсутствует.

Символы и строки: основные операции

В заданиях, связанных с поиском и заменой подстрок, можно считать, что исходная строка не содержит перекрывающихся вхождений требуемых подстрок. Кроме этого, можно также считать, что удаление или замена любого вхождения подстроки не приведет к появлению в строке новых вхождений данной подстроки.

String1. Дан символ C. Вывести его код (т. е. номер в кодовой таблице).

String2. Дано целое число N (32 ≤ N ≤ 126). Вывести символ с кодом, равным N.

String3. Дан символ C. Вывести два символа, первый из которых предшествует символу C в кодовой таблице, а второй следует за символом C.

String4. Дано целое число N (1 ≤ N ≤ 26). Вывести N первых прописных (т. е. заглавных) букв латинского алфавита.

String5. Дано целое число N (1 ≤ N ≤ 26). Вывести N последних строчных (т. е. маленьких) букв латинского алфавита в обратном порядке (начиная с буквы «z»).

String6. Дан символ C, изображающий цифру или букву (латинскую или русскую). Если C изображает цифру, то вывести строку «digit», если латинскую букву — вывести строку «lat», если русскую — вывести строку «rus».

String7. Дана непустая строка. Вывести коды ее первого и последнего символа.

String8. Дано целое число N (> 0) и символ C. Вывести строку длины N, которая состоит из символов C.

String9. Дано четное число N (> 0) и символы C1 и C2. Вывести строку длины N, которая состоит из чередующихся символов C1 и C2, начиная с C1.

String10. Дана строка. Вывести строку, содержащую те же символы, но расположенные в обратном порядке.

String11. Дана непустая строка S. Вывести строку, содержащую символы строки S, между которыми вставлено по одному пробелу.

String12. Дана непустая строка S и целое число N (> 0). Вывести строку, содержащую символы строки S, между которыми вставлено по N символов «*» (звездочка).

String13. Дана строка. Подсчитать количество содержащихся в ней цифр.

String14. Дана строка. Подсчитать количество содержащихся в ней прописных латинских букв.

String15. Дана строка. Подсчитать общее количество содержащихся в ней строчных латинских и русских букв.

String16. Дана строка. Преобразовать в ней все прописные латинские буквы в строчные.

String17. Дана строка. Преобразовать в ней все строчные буквы (как латинские, так и русские) в прописные.

String18. Дана строка. Преобразовать в ней все строчные буквы (как латинские, так и русские) в прописные, а прописные — в строчные.

String19. Дана строка. Если она представляет собой запись целого числа, то вывести 1, если вещественного (с дробной частью) — вывести 2; если строку нельзя преобразовать в число, то вывести 0. Считать, что дробная часть вещественного числа отделяется от его целой части десятичной точкой «.».

String20. Дано целое положительное число. Вывести символы, изображающие цифры этого числа (в порядке слева направо).

String21. Дано целое положительное число. Вывести символы, изображающие цифры этого числа (в порядке справа налево).

String22. Дана строка, изображающая целое положительное число. Вывести сумму цифр этого числа.

String23. Дана строка, изображающая арифметическое выражение вида «<цифра>±<цифра>±…±<цифра>», где на месте знака операции «±» находится символ «+» или «−» (например, «4+7−2−8»). Вывести значение данного выражения (целое число).

String24. Дана строка, изображающая двоичную запись целого положительного числа. Вывести строку, изображающую десятичную запись этого же числа.

String25. Дана строка, изображающая десятичную запись целого положительного числа. Вывести строку, изображающую двоичную запись этого же числа.

String26. Дано целое число N (> 0) и строка S. Преобразовать строку S в строку длины N следующим образом: если длина строки S больше N, то отбросить первые символы, если длина строки S меньше N, то в ее начало добавить символы «.» (точка).

String27. Даны целые положительные числа N1 и N2 и строки S1 и S2. Получить из этих строк новую строку, содержащую первые N1 символов строки S1 и последние N2 символов строки S2 (в указанном порядке).

String28. Дан символ C и строка S. Удвоить каждое вхождение символа C в строку S.

String29. Дан символ C и строки S, S0. Перед каждым вхождением символа C в строку S вставить строку S0.

String30. Дан символ C и строки S, S0. После каждого вхождения символа C в строку S вставить строку S0.

String31. Даны строки S и S0. Проверить, содержится ли строка S0 в строке S. Если содержится, то вывести True, если не содержится, то вывести False.

String32. Даны строки S и S0. Найти количество вхождений строки S0 в строку S.

String33. Даны строки S и S0. Удалить из строки S первую подстроку, совпадающую с S0. Если совпадающих подстрок нет, то вывести строку S без изменений.

String34. Даны строки S и S0. Удалить из строки S последнюю подстроку, совпадающую с S0. Если совпадающих подстрок нет, то вывести строку S без изменений.

String35. Даны строки S и S0. Удалить из строки S все подстроки, совпадающие с S0. Если совпадающих подстрок нет, то вывести строку S без изменений.

String36. Даны строки S, S1 и S2. Заменить в строке S первое вхождение строки S1 на строку S2.

String37. Даны строки S, S1 и S2. Заменить в строке S последнее вхождение строки S1 на строку S2.

String38. Даны строки S, S1 и S2. Заменить в строке S все вхождения строки S1 на строку S2.

String39. Дана строка, содержащая по крайней мере один символ пробела. Вывести подстроку, расположенную между первым и вторым пробелом исходной строки. Если строка содержит только один пробел, то вывести пустую строку.

String40. Дана строка, содержащая по крайней мере один символ пробела. Вывести подстроку, расположенную между первым и последним пробелом исходной строки. Если строка содержит только один пробел, то вывести пустую строку.

Анализ и преобразование слов в строке

Во всех заданиях данной подгруппы предполагается, что исходные строки являются непустыми и не содержат начальных и конечных пробелов.

String41. Дана строка, состоящая из русских слов, разделенных пробелами (одним или несколькими). Найти количество слов в строке.

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

String43. Дана строка, состоящая из русских слов, набранных заглавными буквами и разделенных пробелами (одним или несколькими). Найти количество слов, которые содержат хотя бы одну букву «А».

String44. Дана строка, состоящая из русских слов, набранных заглавными буквами и разделенных пробелами (одним или несколькими). Найти количество слов, которые содержат ровно три буквы «А».

String45. Дана строка, состоящая из русских слов, разделенных пробелами (одним или несколькими). Найти длину самого короткого слова.

String46. Дана строка, состоящая из русских слов, разделенных пробелами (одним или несколькими). Найти длину самого длинного слова.

String47. Дана строка, состоящая из русских слов, разделенных пробелами (одним или несколькими). Вывести строку, содержащую эти же слова, разделенные одним символом «.» (точка). В конце строки точку не ставить.

String48. Дана строка, состоящая из русских слов, набранных заглавными буквами и разделенных пробелами (одним или несколькими). Преобразовать каждое слово в строке, заменив в нем все последующие вхождения его первой буквы на символ «.» (точка). Например, слово «МИНИМУМ» надо преобразовать в «МИНИ.У.». Количество пробелов между словами не изменять.

String49. Дана строка, состоящая из русских слов, набранных заглавными буквами и разделенных пробелами (одним или несколькими). Преобразовать каждое слово в строке, заменив в нем все предыдущие вхождения его последней буквы на символ «.» (точка). Например, слово «МИНИМУМ» надо преобразовать в «.ИНИ.УМ». Количество пробелов между словами не изменять.

String50. Дана строка, состоящая из русских слов, разделенных пробелами (одним или несколькими). Вывести строку, содержащую эти же слова, разделенные одним пробелом и расположенные в обратном порядке.

String51. Дана строка, состоящая из русских слов, набранных заглавными буквами и разделенных пробелами (одним или несколькими). Вывести строку, содержащую эти же слова, разделенные одним пробелом и расположенные в алфавитном порядке.

String52. Дана строка-предложение на русском языке. Преобразовать строку так, чтобы каждое слово начиналось с заглавной буквы. Словом считать набор символов, не содержащий пробелов и ограниченный пробелами или началом/концом строки. Слова, не начинающиеся с буквы, не изменять.

String53. Дана строка-предложение на русском языке. Подсчитать количество содержащихся в строке знаков препинания.

String54. Дана строка-предложение на русском языке. Подсчитать количество содержащихся в строке гласных букв.

String55. Дана строка-предложение на русском языке. Вывести самое длинное слово в предложении. Если таких слов несколько, то вывести первое из них. Словом считать набор символов, не содержащий пробелов, знаков препинания и ограниченный пробелами, знаками препинания или началом/концом строки.

String56. Дана строка-предложение на русском языке. Вывести самое короткое слово в предложении. Если таких слов несколько, то вывести последнее из них. Словом считать набор символов, не содержащий пробелов, знаков препинания и ограниченный пробелами, знаками препинания или началом/концом строки.

String57. Дана строка-предложение с избыточными пробелами между словами. Преобразовать ее так, чтобы между словами был ровно один пробел.

Символы и строки: дополнительные задания

String58. Дана строка, содержащая полное имя файла, т. е. имя диска, список каталогов (путь), собственно имя и расширение. Выделить из этой строки имя файла (без расширения).

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

String60. Дана строка, содержащая полное имя файла. Выделить из этой строки название первого каталога (без символов «\»). Если файл содержится в корневом каталоге, то вывести символ «\».

String61. Дана строка, содержащая полное имя файла. Выделить из этой строки название последнего каталога (без символов «\»). Если файл содержится в корневом каталоге, то вывести символ «\».

String62. Дана строка-предложение на русском языке. Зашифровать ее, выполнив циклическую замену каждой буквы на следующую за ней в алфавите и сохранив при этом регистр букв («А» перейдет в «Б», «а» — в «б», «Б» — в «В», «я» — в «а» и т. д.). Букву «ё» в алфавите не учитывать («е» должна переходить в «ж»). Знаки препинания и пробелы не изменять.

String63. Дана строка-предложение на русском языке и число K (0 < K < 10). Зашифровать строку, выполнив циклическую замену каждой буквы на букву того же регистра, расположенную в алфавите на K-й позиции после шифруемой буквы (например, для K = 2 «А» перейдет в «В», «а» — в «в», «Б» — в «Г», «я» — в «б» и т. д.). Букву «ё» в алфавите не учитывать, знаки препинания и пробелы не изменять.

String64. Дано зашифрованное предложение на русском языке (способ шифрования описан в задании String63) и кодовое смещение K (0 < K < 10). Расшифровать предложение.

String65. Дано зашифрованное предложение на русском языке (способ шифрования описан в задании String63) и его расшифрованный первый символ C. Найти кодовое смещение K и расшифровать предложение.

String66. Дана строка-предложение. Зашифровать ее, поместив вначале все символы, расположенные на четных позициях строки, а затем, в обратном порядке, все символы, расположенные на нечетных позициях (например, строка «Программа» превратится в «ргамамроП»).

String67. Дано предложение, зашифрованное по правилу, описанному в задании String66. Расшифровать это предложение.

String68. Дана строка, содержащая цифры и строчные латинские буквы. Если буквы в строке упорядочены по алфавиту, то вывести 0; в противном случае вывести номер первого символа строки, нарушающего алфавитный порядок.

String69. Дана строка, содержащая латинские буквы и круглые скобки. Если скобки расставлены правильно (т. е. каждой открывающей соответствует одна закрывающая), то вывести число 0. В противном случае вывести или номер позиции, в которой расположена первая ошибочная закрывающая скобка, или, если закрывающих скобок не хватает, число −1.

String70. Дана строка, содержащая латинские буквы и скобки трех видов: «()», «[]», «{}». Если скобки расставлены правильно (т. е. каждой открывающей соответствует закрывающая скобка того же вида), то вывести число 0. В противном случае вывести или номер позиции, в которой расположена первая ошибочная скобка, или, если закрывающих скобок не хватает, число −1.


Группы заданий

Двоичные файлы: группа File

Условие вида «дан файл (целых чисел, вещественных чисел и т. д.)» означает, что в наборе исходных данных указано имя данного файла (текстовая строка), а сам исходный файл существует и находится в текущем каталоге. Если существование исходных файлов требуется проверять в ходе выполнения задания, то это особо оговаривается в формулировке задания. Элементы исходных файлов следует считывать с помощью стандартных процедур используемого языка программирования.

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

Под размером типизированного файла всегда подразумевается количество содержащихся в нем элементов указанного типа (а не количество байтов, как это принято в операционной системе). В заданиях предполагается, что файловые элементы нумеруются от 1, поэтому в языке Паскаль для перехода к K-му элементу файла F необходимо использовать процедуру Seek(F, K − 1).

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

Двоичные файлы: основные операции

File1. Дана строка S. Если S является допустимым именем файла, то создать пустой файл с этим именем и вывести True. Если файл с именем S создать нельзя, то вывести False.

File2. Дано имя файла и целое число N (> 1). Создать файл целых чисел с данным именем и записать в него N первых положительных четных чисел (2, 4, …).

File3. Дано имя файла и вещественные числа A и D. Создать файл вещественных чисел с данным именем и записать в него 10 первых членов арифметической прогрессии с начальным членом A и разностью D:

A, A + D, A + 2·D, A + 3·D, … .

File4. Даны имена четырех файлов. Найти количество файлов с указанными именами, которые имеются в текущем каталоге.

File5. Дано имя файла целых чисел. Найти количество элементов, содержащихся в данном файле. Если файла с таким именем не существует, то вывести −1.

File6. Дано целое число K и файл, содержащий неотрицательные целые числа. Вывести K-й элемент файла (элементы нумеруются от 1). Если такой элемент отсутствует, то вывести −1.

File7. Дан файл целых чисел, содержащий не менее четырех элементов. Вывести первый, второй, предпоследний и последний элементы данного файла.

File8. Даны имена двух файлов вещественных чисел. Известно, что первый из них существует и является непустым, а второй в текущем каталоге отсутствует. Создать отсутствующий файл и записать в него начальный и конечный элементы существующего файла (в указанном порядке).

File9. Даны имена двух файлов вещественных чисел. Известно, что один из них (не обязательно первый) существует и является непустым, а другой в текущем каталоге отсутствует. Создать отсутствующий файл и записать в него конечный и начальный элементы существующего файла (в указанном порядке).

File10. Дан файл целых чисел. Создать новый файл, содержащий те же элементы, что и исходный файл, но в обратном порядке.

File11. Дан файл вещественных чисел. Создать два новых файла, первый из которых содержит элементы исходного файла с нечетными номерами (1, 3, …), а второй — с четными (2, 4, …).

File12. Дан файл целых чисел. Создать два новых файла, первый из которых содержит четные числа из исходного файла, а второй — нечетные (в том же порядке). Если четные или нечетные числа в исходном файле отсутствуют, то соответствующий результирующий файл оставить пустым.

File13. Дан файл целых чисел. Создать два новых файла, первый из которых содержит положительные числа из исходного файла (в обратном порядке), а второй — отрицательные (также в обратном порядке). Если положительные или отрицательные числа в исходном файле отсутствуют, то соответствующий результирующий файл оставить пустым.

File14. Дан файл вещественных чисел. Найти среднее арифметическое его элементов.

File15. Дан файл вещественных чисел. Найти сумму его элементов с четными номерами.

File16. Дан файл целых чисел. Найти количество содержащихся в нем серий (т. е. наборов последовательно расположенных одинаковых элементов). Например, для файла с элементами 1, 5, 5, 5, 4, 4, 5 результат равен 4.

File17. Дан файл целых чисел. Создать новый файл целых чисел, содержащий длины всех серий исходного файла (серией называется набор последовательно расположенных одинаковых элементов, а длиной серии — количество этих элементов). Например, для исходного файла с элементами 1, 5, 5, 5, 4, 4, 5 содержимое результирующего файла должно быть следующим: 1, 3, 2, 1.

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

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

File20. Дан файл вещественных чисел. Найти общее количество его локальных экстремумов, т. е. локальных минимумов и локальных максимумов (определения локального минимума и локального максимума даны в заданиях File18 и File19).

File21. Дан файл вещественных чисел. Создать файл целых чисел, содержащий номера всех локальных максимумов исходного файла в порядке возрастания (определение локального максимума дано в задании File19).

File22. Дан файл вещественных чисел. Создать файл целых чисел, содержащий номера всех локальных экстремумов исходного файла в порядке убывания (определение локального экстремума дано в задании File20).

File23. Дан файл вещественных чисел. Создать файл целых чисел, содержащий длины всех убывающих последовательностей элементов исходного файла. Например, для исходного файла с элементами 1.7, 4.5, 3.4, 2.2, 8.5, 1.2 содержимое результирующего файла должно быть следующим: 3, 2.

File24. Дан файл вещественных чисел. Создать файл целых чисел, содержащий длины всех монотонных последовательностей элементов исходного файла. Например, для исходного файла с элементами 1.7, 4.5, 3.4, 2.2, 8.5, 1.2 содержимое результирующего файла должно быть следующим: 2, 3, 2, 2.

File25. Дан файл вещественных чисел. Заменить в нем все элементы на их квадраты.

File26. Дан файл вещественных чисел. Поменять в нем местами минимальный и максимальный элементы.

File27. Дан файл целых чисел с элементами A1, A2, …, AN (N — количество элементов в файле). Заменить исходное расположение его элементов на следующее:

A1, AN, A2, AN−1, A3, … .

File28. Дан файл вещественных чисел. Заменить в файле каждый элемент, кроме начального и конечного, на его среднее арифметическое с предыдущим и последующим элементом.

File29. Дан файл целых чисел, содержащий более 50 элементов. Уменьшить его размер до 50 элементов, удалив из файла необходимое количество конечных элементов.

File30. Дан файл целых чисел, содержащий четное количество элементов. Удалить из данного файла вторую половину элементов.

File31. Дан файл целых чисел, содержащий более 50 элементов. Уменьшить его размер до 50 элементов, удалив из файла необходимое количество начальных элементов.

File32. Дан файл целых чисел, содержащий четное количество элементов. Удалить из данного файла первую половину элементов.

File33. Дан файл целых чисел. Удалить из него все элементы с четными номерами.

File34. Дан файл целых чисел. Удалить из него все отрицательные числа.

File35. Дан файл целых чисел, содержащий менее 50 элементов. Увеличить его размер до 50 элементов, записав в начало файла необходимое количество нулей.

File36. Дан файл целых чисел. Удвоить его размер, записав в конец файла все его исходные элементы (в том же порядке).

File37. Дан файл целых чисел. Удвоить его размер, записав в конец файла все его исходные элементы (в обратном порядке).

File38. Дан файл целых чисел. Продублировать в нем все элементы с нечетными номерами.

File39. Дан файл целых чисел. Продублировать в нем все числа, принадлежащие диапазону 5–10.

File40. Дан файл целых чисел. Заменить в нем каждый элемент с четным номером на два нуля.

File41. Дан файл целых чисел. Заменить в нем каждое положительное число на три нуля.

Обработка нетипизированных двоичных файлов

File42. Даны два файла произвольного типа. Поменять местами их содержимое.

File43. Дан файл произвольного типа. Создать его копию с новым именем.

File44. Даны три файла одного и того же типа, но разного размера. Заменить содержимое самого длинного файла на содержимое самого короткого.

File45. Даны три файла одного и того же типа, но разного размера. Заменить содержимое самого короткого файла на содержимое самого длинного.

File46. Дана строка S0, целое число N (≤ 4) и N файлов одного и того же типа с именами S1, …, SN. Объединить содержимое этих файлов (в указанном порядке) в новом файле с именем S0.

File47. Даны два файла одного и того же типа. Добавить к первому файлу содержимое второго файла, а ко второму файлу — содержимое первого.

Работа с несколькими числовыми файлами. Файлы-архивы

File48. Даны три файла целых чисел одинакового размера с именами SA, SB, SC и строка SD. Создать новый файл с именем SD, в котором чередовались бы элементы исходных файлов с одним и тем же номером:

A1, B1, C1, A2, B2, C2, … .

File49. Даны четыре файла целых чисел разного размера с именами SA, SB, SC, SD и строка SE. Создать новый файл с именем SE, в котором чередовались бы элементы исходных файлов с одним и тем же номером (как в задании File48). «Лишние» элементы более длинных файлов в результирующий файл не записывать.

File50. Даны два файла вещественных чисел с именами S1 и S2, элементы которых упорядочены по возрастанию. Объединить эти файлы в новый файл с именем S3 так, чтобы его элементы также оказались упорядоченными по возрастанию.

File51. Даны три файла вещественных чисел с именами S1, S2 и S3, элементы которых упорядочены по убыванию. Объединить эти файлы в новый файл с именем S4 так, чтобы его элементы также оказались упорядоченными по убыванию.

File52. Дана строка S0, целое число N (≤ 4) и N файлов целых чисел с именами S1, …, SN. Объединить их содержимое в новом файле-архиве с именем S0, используя следующий формат: в первом элементе файла-архива хранится число N, в следующих N элементах хранится размер (число элементов) каждого из исходных файлов, а затем последовательно размещаются данные из каждого исходного файла.

File53. Дана строка S, целое число N (> 0) и файл-архив целых чисел, содержащий данные из нескольких файлов в формате, описанном в задании File52. Восстановить из файла-архива файл с номером N и сохранить его под именем S. Если файл-архив содержит данные из менее чем N файлов, то оставить результирующий файл пустым.

File54. Дана строка S и файл-архив целых чисел, содержащий данные из нескольких (не более шести) файлов в формате, описанном в задании File52. Для каждого из файлов, содержащихся в архиве, найти среднее арифметическое всех его элементов (вещественное число) и записать найденные числа (в том же порядке) в файл вещественных чисел с именем S.

File55. Дана строка S0, целое число N (≤ 4) и N файлов целых чисел с именами S1, …, SN. Объединить их содержимое в новом файле-архиве с именем S0, последовательно записывая в него следующие данные: размер (число элементов) первого исходного файла и все элементы этого файла, размер второго исходного файла и все его элементы, …, размер N-го исходного файла и все его элементы.

File56. Дана строка S, целое число N (> 0) и файл-архив целых чисел, содержащий данные из нескольких файлов в формате, описанном в задании File55. Восстановить из файла-архива файл с номером N и сохранить его под именем S. Если файл-архив содержит данные из менее чем N файлов, то оставить результирующий файл пустым.

File57. Даны строки S1, S2 и файл-архив целых чисел, содержащий данные из нескольких файлов в формате, описанном в задании File55. Создать новые файлы целых чисел с именами S1 и S2 и записать в первый из них начальные элементы всех файлов, содержащихся в архиве, а во второй — конечные элементы этих файлов (в том же порядке).

Символьные и строковые файлы

Строковым файлом называется типизированный файл, элементами которого являются текстовые строки. В системе Borland Delphi файловые переменные для строковых файлов необходимо описывать как file of ShortString; этот же тип следует указывать при описании переменных, которые используются в процедурах ввода-вывода для строковых файлов; в системе Pascal ABC строковые файлы описываются как file of string.

File58. Дан символьный файл, содержащий по крайней мере один символ пробела. Удалить все его элементы, расположенные после первого символа пробела, включая и этот пробел.

File59. Дан символьный файл, содержащий по крайней мере один символ пробела. Удалить все его элементы, расположенные после последнего символа пробела, включая и этот пробел.

File60. Дан символьный файл, содержащий по крайней мере один символ пробела. Удалить все его элементы, расположенные перед первым символом пробела, включая и этот пробел.

File61. Дан символьный файл, содержащий по крайней мере один символ пробела. Удалить все его элементы, расположенные перед последним символом пробела, включая и этот пробел.

File62. Дан символьный файл. Упорядочить его элементы по возрастанию их кодов.

File63. Дано целое число K (> 0) и строковый файл. Создать два новых файла: строковый, содержащий первые K символов каждой строки исходного файла, и символьный, содержащий K-й символ каждой строки (если длина строки меньше K, то в строковый файл записывается вся строка, а в символьный файл записывается пробел).

File64. Дан строковый файл. Создать новый строковый файл, содержащий все строки исходного файла наименьшей длины (в том же порядке).

File65. Дан строковый файл. Создать новый строковый файл, содержащий все строки исходного файла наибольшей длины (в обратном порядке).

File66. Дан строковый файл. Создать новый строковый файл, в котором строки из исходного файла располагались бы в лексикографическом порядке, т. е. по возрастанию кодов их символов, начиная с первого символа.

File67. Дан строковый файл, содержащий даты в формате «день/месяц/год», причем под день и месяц отводится по две позиции, а под год — четыре (например, «16/04/2001»). Создать два файла целых чисел, первый из которых содержит значения дней, а второй — значения месяцев для дат из исходного строкового файла (в том же порядке).

File68. Дан строковый файл, содержащий даты в формате, описанном в задании File67. Создать два файла целых чисел, первый из которых содержит значения месяцев, а второй — значения лет для дат из исходного строкового файла (в обратном порядке).

File69. Дан строковый файл, содержащий даты в формате, описанном в задании File67. Создать новый строковый файл, содержащий все летние даты из исходного файла (в том же порядке). Если даты с требуемым временем года в файле отсутствуют, то оставить результирующий файл пустым.

File70. Дан строковый файл, содержащий даты в формате, описанном в задании File67. Создать новый строковый файл, содержащий все зимние даты из исходного файла (в обратном порядке). Если даты с требуемым временем года в файле отсутствуют, то оставить результирующий файл пустым.

File71. Дан строковый файл, содержащий даты в формате, описанном в задании File67. Найти строку, содержащую самую раннюю весеннюю дату. Если даты с требуемым временем года в файле отсутствуют, то вывести пустую строку.

File72. Дан строковый файл, содержащий даты в формате, описанном в задании File67. Найти строку, содержащую самую позднюю осеннюю дату. Если даты с требуемым временем года в файле отсутствуют, то вывести пустую строку.

File73. Дан строковый файл, содержащий даты в формате, описанном в задании File67. Создать новый строковый файл, в котором даты из исходного файла располагались бы в порядке убывания.

Использование файлов для работы с матрицами

Матрицей размера M × N называется прямоугольная таблица чисел, содержащая M строк и N столбцов. Для работы с матрицами обычно используются двумерные массивы (см. задания группы Matrix). Данная подгруппа посвящена способам обработки матриц, хранящихся в типизированных файлах на внешних носителях (дисках). Как и в остальных заданиях на обработку файловых данных, при выполнении заданий из данной подгруппы не следует использовать вспомогательные массивы, содержащие все файловые элементы.

В заданиях данной подгруппы используются дополнительные понятия теории матриц. Приведем определения этих понятий.

Пусть A — матрица размера M × N. Матрица B называется транспонированной к матрице A, если она имеет размер N × M и ее элементы удовлетворяют следующему соотношению:

BI,J = AJ,I, I = 1, …, N, J = 1, … M.

Пусть A — матрица размера M × N, B — матрица размера N × P. Матрица C называется произведением матриц A и B (и обозначается A·B), если она имеет размер M × P и ее элементы удовлетворяют следующему соотношению:

CI,J = AI,1·B1,J + AI,2·B2,J + … + A1,N·BN,J, I = 1, …, M, J = 1, … P.

Квадратная матрица A называется верхнетреугольной, если все ее элементы, лежащие ниже главной диагонали, равны нулю (определение главной диагонали см. в задании Matrix80):

AI,J = 0, I > J.

Квадратная матрица A называется нижнетреугольной, если все ее элементы, лежащие выше главной диагонали, равны нулю:

AI,J = 0, I < J.

Квадратная матрица A называется трехдиагональной, если равны нулю все ее элементы, не лежащие на главной диагонали и на двух диагоналях, примыкающих к главной:

AI,J = 0, |I − J| > 1.

File74. Даны два целых числа I, J и файл вещественных чисел, содержащий элементы квадратной матрицы (по строкам). Вывести элемент матрицы, расположенный в I-й строке и J-м столбце (строки и столбцы нумеруются от 1). Если требуемый элемент отсутствует, то вывести 0.

File75. Дан файл вещественных чисел, содержащий элементы квадратной матрицы (по строкам). Создать новый файл, содержащий элементы матрицы, транспонированной к исходной.

File76. Даны два файла вещественных чисел с именами SA и SB, содержащие элементы квадратных матриц A и B (по строкам). Создать новый файл с именем SC, содержащий элементы произведения A·B. Если матрицы A и B нельзя перемножать, то оставить файл SC пустым.

File77. Даны два целых числа I, J и файл вещественных чисел, содержащий элементы прямоугольной матрицы (по строкам), причем первый элемент файла содержит количество столбцов матрицы. Вывести элемент матрицы, расположенный в I-й строке и J-м столбце (строки и столбцы нумеруются от 1). Если требуемый элемент отсутствует, то вывести 0.

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

File79. Даны два файла вещественных чисел с именами SA и SB, содержащие элементы прямоугольных матриц A и B (по строкам), причем первый элемент каждого файла содержит количество столбцов соответствующей матрицы. Создать файл той же структуры с именем SC, содержащий элементы произведения A·B. Если матрицы A и B нельзя перемножать, то оставить файл SC пустым.

File80. Дан файл вещественных чисел, содержащий элементы верхнетреугольной матрицы (по строкам). Создать новый файл, содержащий элементы ненулевой части данной матрицы (по строкам).

File81. Дан файл вещественных чисел, содержащий элементы нижнетреугольной матрицы (по строкам). Создать новый файл, содержащий элементы ненулевой части данной матрицы (по строкам).

File82. Дан файл вещественных чисел, содержащий элементы трехдиагональной матрицы (по строкам). Создать новый файл, содержащий элементы ненулевой части данной матрицы (по строкам).

File83. Даны два целых числа I, J и файл вещественных чисел, содержащий ненулевую часть верхнетреугольной матрицы (по строкам). Вывести порядок матрицы и ее элемент, расположенный в I-й строке и J-м столбце (строки и столбцы нумеруются от 1). Если требуемый элемент находится в нулевой части матрицы, то вывести 0; если элемент отсутствует, то вывести −1.

File84. Даны два целых числа I, J и файл вещественных чисел, содержащий ненулевую часть нижнетреугольной матрицы (по строкам). Вывести порядок матрицы и ее элемент, расположенный в I-й строке и J-м столбце (строки и столбцы нумеруются от 1). Если требуемый элемент находится в нулевой части матрицы, то вывести 0; если элемент отсутствует, то вывести −1.

File85. Даны два целых числа I, J и файл вещественных чисел, содержащий ненулевую часть трехдиагональной матрицы (по строкам). Вывести порядок матрицы и ее элемент, расположенный в I-й строке и J-м столбце (строки и столбцы нумеруются от 1). Если требуемый элемент находится в нулевой части матрицы, то вывести 0; если элемент отсутствует, то вывести −1.

File86. Дан файл вещественных чисел, содержащий ненулевую часть верхнетреугольной матрицы (по строкам). Создать новый файл, содержащий все элементы данной матрицы (по строкам).

File87. Дан файл вещественных чисел, содержащий ненулевую часть нижнетреугольной матрицы (по строкам). Создать новый файл, содержащий все элементы данной матрицы (по строкам).

File88. Дан файл вещественных чисел, содержащий ненулевую часть трехдиагональной матрицы (по строкам). Создать новый файл, содержащий все элементы данной матрицы (по строкам).

File89. Даны два файла вещественных чисел с именами SA и SB, содержащие ненулевые части верхнетреугольных матриц A и B (по строкам). Создать новый файл с именем SC, содержащий ненулевую часть произведения A·B (по строкам). Если матрицы A и B нельзя перемножать, то оставить файл SC пустым.

File90. Даны два файла вещественных чисел с именами SA и SB, содержащие ненулевые части нижнетреугольных матриц A и B (по строкам). Создать новый файл с именем SC, содержащий ненулевую часть произведения A·B (по строкам). Если матрицы A и B нельзя перемножать, то оставить файл SC пустым.


Группы заданий

Текстовые файлы: группа Text

Условие вида «дан текстовый файл» означает, что в наборе исходных данных указано имя данного файла (текстовая строка). Все исходные файлы в заданиях данной группы считаются существующими. Элементы исходных файлов следует считывать с помощью стандартных процедур используемого языка программирования.

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

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

Используемые в заданиях типизированные файлы удовлетворяют условиям, которые перечислены в начале описания группы «Двоичные файлы».

Текстовые файлы: основные операции

Text1. Дано имя файла и целые положительные числа N и K. Создать текстовый файл с указанным именем и записать в него N строк, каждая из которых состоит из K символов «*» (звездочка).

Text2. Дано имя файла и целое число N (0 < N < 27). Создать текстовый файл с указанным именем и записать в него N строк: первая строка должна содержать строчную (т. е. маленькую) латинскую букву «a», вторая — буквы «ab», третья — буквы «abc» и т. д.; последняя строка должна содержать N начальных строчных латинских букв в алфавитном порядке.

Text3. Дано имя файла и целое число N (0 < N < 27). Создать текстовый файл с указанным именем и записать в него N строк длины N; строка с номером K (K = 1, …, N) должна содержать K начальных прописных (т. е. заглавных) латинских букв, дополненных справа символами «*» (звездочка). Например, для N = 4 файл должен содержать строки «A***», «AB**», «ABC*», «ABCD».

Text4. Дан текстовый файл. Вывести количество содержащихся в нем символов и строк (маркеры концов строк EOLN и конца файла EOF при подсчете количества символов не учитывать).

Text5. Дана строка S и текстовый файл. Добавить строку S в конец файла.

Text6. Даны два текстовых файла. Добавить в конец первого файла содержимое второго файла.

Text7. Дана строка S и текстовый файл. Добавить строку S в начало файла.

Text8. Даны два текстовых файла. Добавить в начало первого файла содержимое второго файла.

Text9. Дано целое число K и текстовый файл. Вставить пустую строку перед строкой файла с номером K. Если строки с таким номером нет, то оставить файл без изменений.

Text10. Дано целое число K и текстовый файл. Вставить пустую строку после строки файла с номером K. Если строки с таким номером нет, то оставить файл без изменений.

Text11. Дан текстовый файл. Продублировать в нем все пустые строки.

Text12. Дана строка S и текстовый файл. Заменить в файле все пустые строки на строку S.

Text13. Дан непустой текстовый файл. Удалить из него первую строку.

Text14. Дан непустой текстовый файл. Удалить из него последнюю строку.

Text15. Дано целое число K и текстовый файл. Удалить из файла строку с номером K. Если строки с таким номером нет, то оставить файл без изменений.

Text16. Дан текстовый файл. Удалить из него все пустые строки.

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

Text18. Дано целое число K и текстовый файл. Удалить из каждой строки файла первые K символов (если длина строки меньше K, то удалить из нее все символы).

Text19. Дан текстовый файл. Заменить в нем все прописные русские буквы на строчные, а все строчные — на прописные.

Text20. Дан текстовый файл. Заменить в нем все подряд идущие пробелы на один пробел.

Text21. Дан текстовый файл, содержащий более трех строк. Удалить из него последние три строки.

Text22. Дано целое число K (0 < K < 10) и текстовый файл, содержащий более K строк. Удалить из файла последние K строк.

Text23. Дано целое число K (0 < K < 10) и текстовый файл, содержащий более K строк. Создать новый текстовый файл, содержащий K последних строк исходного файла.

Анализ и форматирование текста

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

Text25. Дано целое число K и текстовый файл. Удалить из файла абзац с номером K (абзацы отделяются друг от друга одной или несколькими пустыми строками). Пустые строки, предшествующие и следующие за удаляемым абзацем, не удалять. Если абзац с данным номером отсутствует, то оставить файл без изменений.

Text26. Дан текстовый файл. Найти количество абзацев в тексте, если первая строка каждого абзаца начинается с 5 пробелов («красная строка»). Пустые строки между абзацами не учитывать.

Text27. Дано целое число K и текстовый файл. Удалить из файла абзац с номером K (абзацы выделяются с помощью красной строки — см. задание Text26). Пустые строки между абзацами не учитывать и не удалять. Если абзац с данным номером отсутствует, то оставить файл без изменений.

Text28. Дан текстовый файл. Абзацы выделяются в нем с помощью красной строки (см. задание Text26), а пустых строк нет. Вставить между соседними абзацами по одной пустой строке (в начало и конец файла пустые строки не добавлять).

Text29. Дан текстовый файл. Вывести первое слово текста наибольшей длины. Словом считать набор символов, не содержащий пробелов и ограниченный пробелами или началом/концом строки.

Text30. Дан текстовый файл. Вывести последнее слово текста наименьшей длины. Словом считать набор символов, не содержащий пробелов и ограниченный пробелами или началом/концом строки.

Text31. Дано целое число K и текстовый файл. Создать строковый файл и записать в него все слова длины K из исходного файла. Словом считать набор символов, не содержащий пробелов, знаков препинания и ограниченный пробелами, знаками препинания или началом/концом строки. Если исходный файл не содержит слов длины K, то оставить результирующий файл пустым.

Text32. Дан символ C — прописная (заглавная) русская буква и текстовый файл. Создать строковый файл и записать в него все слова из исходного файла, начинающиеся на эту букву (прописную или строчную). Словом считать набор символов, не содержащий пробелов, знаков препинания и ограниченный пробелами, знаками препинания или началом/концом строки. Если исходный файл не содержит подходящих слов, то оставить результирующий файл пустым.

Text33. Дан символ C — строчная (маленькая) русская буква и текстовый файл. Создать строковый файл и записать в него все слова из исходного файла, содержащие хотя бы одну букву C (прописную или строчную). Словом считать набор символов, не содержащий пробелов, знаков препинания и ограниченный пробелами, знаками препинания или началом/концом строки. Если исходный файл не содержит подходящих слов, то оставить результирующий файл пустым.

Text34. Дан текстовый файл, содержащий текст, выровненный по левому краю. Выровнять текст по правому краю, добавив в начало каждой непустой строки нужное количество пробелов (ширину текста считать равной 50).

Text35. Дан текстовый файл, содержащий текст, выровненный по левому краю. Выровнять текст по центру, добавив в начало каждой непустой строки нужное количество пробелов (ширину текста считать равной 50). Строки нечетной длины перед центрированием дополнять слева пробелом.

Text36. Дан текстовый файл, содержащий текст, выровненный по правому краю. Выровнять текст по центру, удалив из каждой непустой строки половину начальных пробелов. В строках с нечетным количеством начальных пробелов перед центрированием удалять первый начальный пробел.

Text37. Дан текстовый файл, содержащий текст, выровненный по левому краю. Абзацы текста разделяются одной пустой строкой. Выровнять текст по ширине (т. е. и по левому, и по правому краю), увеличив в каждой непустой строке (кроме последних строк абзацев) количество пробелов между словами, начиная с последнего пробела в строке (ширину текста считать равной 50).

Text38. Дано целое число K (> 25) и текстовый файл, содержащий текст, выровненный по левому краю. Абзацы текста отделяются друг от друга одной пустой строкой. Отформатировать текст так, чтобы его ширина не превосходила K позиций, и выровнять текст по левому краю, сохранив деление на абзацы. Пробелы в конце строк удалить. Сохранить отформатированный текст в новом текстовом файле.

Text39. Дано целое число K (> 25) и текстовый файл, содержащий текст, выровненный по левому краю. Абзацы выделяются в нем с помощью красной строки (5 начальных пробелов), а пустых строк нет. Отформатировать текст так, чтобы его ширина не превосходила K позиций, и выровнять текст по левому краю, сохранив деление на абзацы. Пробелы в конце строк удалить. Сохранить отформатированный текст в новом текстовом файле.

Текстовые файлы с числовой информацией

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

Text40. Даны два файла целых чисел одинакового размера. Создать текстовый файл, содержащий эти числа, расположенные в два столбца шириной по 30 символов (в первом столбце содержатся числа из первого исходного файла, во втором — из второго файла). В начало и конец каждой строки текстового файла добавить разделитель «|» (код 124). Числа выравниваются по правому краю столбца.

Text41. Даны три файла целых чисел одинакового размера. Создать текстовый файл, содержащий эти числа, расположенные в три столбца шириной по 20 символов (в каждом столбце содержатся числа из соответствующего исходного файла). В начало и конец каждой строки текстового файла добавить разделитель «|» (код 124). Числа выравниваются по левому краю столбца.

Text42. Даны вещественные числа A, B и целое число N. Создать текстовый файл, содержащий таблицу значений функции (x)1/2 на промежутке [A, B] с шагом (B − A)/N. Таблица состоит из двух столбцов: с аргументами x (10 позиций, из них 4 под дробную часть) и со значениями (x)1/2 (15 позиций, из них 8 под дробную часть). Столбцы выравниваются по правому краю.

Text43. Даны вещественные числа A, B и целое число N. Создать текстовый файл, содержащий таблицу значений функций sin(x) и cos(x) на промежутке [A, B] с шагом (B − A)/N. Таблица состоит из трех столбцов: с аргументами x (8 позиций, из них 4 под дробную часть) и со значениями sin(x) и cos(x) (по 12 позиций, из них 8 под дробную часть). Столбцы выравниваются по правому краю.

Text44. Дан текстовый файл, каждая строка которого изображает целое число, дополненное слева и справа несколькими пробелами. Вывести количество этих чисел и их сумму.

Text45. Дан текстовый файл, каждая строка которого изображает целое или вещественное число, дополненное слева и справа несколькими пробелами (вещественные числа имеют ненулевую дробную часть). Вывести количество чисел с ненулевой дробной частью и их сумму.

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

Text47. Дан текстовый файл, каждая строка которого изображает целое или вещественное число, дополненное слева и справа несколькими пробелами (вещественные числа имеют ненулевую дробную часть). Вывести количество целых чисел и их сумму.

Text48. Дан текстовый файл, каждая строка которого содержит изображения нескольких чисел, разделенные пробелами (вещественные числа имеют ненулевую дробную часть). Создать файл целых чисел, содержащий все целые числа из исходного файла (в том же порядке).

Text49. Дан текстовый файл и файл целых чисел. Добавить в конец каждой строки текстового файла изображение соответствующего числа из файла целых чисел. Если файл целых чисел короче текстового файла, то оставшиеся строки текстового файла не изменять.

Text50. Дан текстовый файл. В каждой его строке первые 30 позиций отводятся под текст, а оставшаяся часть — под вещественное число. Создать два файла: строковый файл, содержащий текстовую часть исходного файла, и файл вещественных чисел, содержащий числа из исходного файла (в том же порядке).

Text51. Дан текстовый файл, содержащий таблицу из трех столбцов вещественных чисел. Ширина столбцов таблицы и способ их выравнивания являются произвольными, специальных символов-разделителей таблица не содержит. Создать три файла вещественных чисел, каждый из которых содержит числа из соответствующего столбца таблицы (в том же порядке).

Text52. Дан текстовый файл, содержащий таблицу из трех столбцов целых чисел. В начале и в конце каждой строки таблицы, а также между ее столбцами располагается символ-разделитель. Ширина столбцов таблицы, способ их выравнивания и вид символа-разделителя являются произвольными. Создать файл целых чисел, содержащий сумму чисел из каждой строки исходной таблицы.

Текстовые файлы: дополнительные задания

Text53. Дан текстовый файл. Создать символьный файл, содержащий все знаки препинания, встретившиеся в текстовом файле (в том же порядке).

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

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

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

Text57. Дан текстовый файл. Подсчитать число появлений в нем каждой строчной (т. е. маленькой) русской буквы и создать строковый файл, элементы которого имеют вид «<буква>–<число ее появлений>» (например, «а–25»). Буквы, отсутствующие в тексте, в файл не включать. Строки упорядочить по возрастанию кодов букв.

Text58. Дан текстовый файл. Подсчитать число появлений в нем каждой строчной (т. е. маленькой) русской буквы и создать строковый файл, элементы которого имеют вид «<буква>–<число ее появлений>» (например, «а–25»). Буквы, отсутствующие в тексте, в файл не включать. Строки упорядочить по убыванию числа появлений букв, а при равном числе появлений — по возрастанию кодов букв.

Text59. Дана строка S, состоящая из 10 цифр, и файл с русским текстом. Зашифровать файл, выполнив циклическую замену каждой русской буквы, стоящей на K-й позиции строки, на букву того же регистра, расположенную в алфавите на SK-м месте после шифруемой буквы (для K = 11 снова используется смещение S1 и т. д.). Букву «ё» в алфавите не учитывать, знаки препинания и пробелы не изменять.

Text60. Дана строка и файл с русским текстом, зашифрованным по правилу, описанному в задании Text59. Данная строка представляет собой первую расшифрованную строку текста. Расшифровать остальные строки и заменить в файле зашифрованный текст на расшифрованный. Если информации для расшифровки недостаточно, то исходный файл не изменять.


Группы заданий

Составные типы данных в процедурах и функциях: группа Param

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

Процедуры и функции: работа с массивами

При вводе исходного массива вначале следует ввести его размер (одно число для одномерных массивов, два числа — количество строк и столбцов — для двумерных массивов-матриц), а затем — все его элементы.

Если в задании явно не указывается размер одномерного массива, являющегося параметром процедуры или функции, то предполагается, что этот размер может изменяться в пределах от 1 до 10. Для двумерных массивов-матриц предполагается, что число их строк и столбцов может меняться от 1 до 10. Индексы начальных элементов как одномерных, так и двумерных массивов всегда считаются равными 1.

При описании процедур, выполняющих преобразование массива, не следует использовать вспомогательный массив того же размера.

Param1. Описать функцию MinElem(A, N) целого типа, находящую минимальный элемент целочисленного массива A размера N. С помощью этой функции найти минимальные элементы массивов A, B, C размера NA, NB, NC соответственно.

Param2. Описать функцию MaxNum(A, N) целого типа, находящую номер максимального элемента вещественного массива A размера N. С помощью этой функции найти номера максимальных элементов массивов A, B, C размера NA, NB, NC соответственно.

Param3. Описать процедуру MinmaxNum(A, N, NMin, NMax), находящую номера минимального и максимального элемента вещественного массива A размера N. Выходные параметры целого типа: NMin (номер минимального элемента) и NMax (номер максимального элемента). С помощью этой процедуры найти номера минимальных и максимальных элементов массивов A, B, C размера NA, NB, NC соответственно.

Param4. Описать процедуру Inv(A, N), меняющую порядок следования элементов вещественного массива A размера N на обратный (инвертирование массива). Массив A является входным и выходным параметром. С помощью этой процедуры инвертировать массивы A, B, C размера NA, NB, NC соответственно.

Param5. Описать процедуру Smooth1(A, N), выполняющую сглаживание вещественного массива A размера N следующим образом: элемент AK заменяется на среднее арифметическое первых K исходных элементов массива A. Массив A является входным и выходным параметром. С помощью этой процедуры выполнить пятикратное сглаживание данного массива A размера N, выводя результаты каждого сглаживания.

Param6. Описать процедуру Smooth2(A, N), выполняющую сглаживание вещественного массива A размера N следующим образом: элемент A1 не изменяется, элемент AK (K = 2, …, N) заменяется на полусумму исходных элементов AK−1 и AK. Массив A является входным и выходным параметром. С помощью этой процедуры выполнить пятикратное сглаживание данного массива A размера N, выводя результаты каждого сглаживания.

Param7. Описать процедуру Smooth3(A, N), выполняющую сглаживание вещественного массива A размера N следующим образом: каждый элемент массива заменяется на его среднее арифметическое с соседними элементами (при вычислении среднего арифметического используются исходные значения соседних элементов). Массив A является входным и выходным параметром. С помощью этой процедуры выполнить пятикратное сглаживание данного массива A размера N, выводя результаты каждого сглаживания.

Param8. Описать процедуру RemoveX(A, N, X), удаляющую из целочисленного массива A размера N элементы, равные целому числу X. Массив A и число N являются входными и выходными параметрами. С помощью этой процедуры удалить числа XA, XB, XC из массивов A, B, C размера NA, NB, NC соответственно и вывести размер и содержимое полученных массивов.

Param9. Описать процедуру RemoveForInc(A, N), удаляющую из вещественного массива A размера N «лишние» элементы так, чтобы оставшиеся элементы оказались упорядоченными по возрастанию: первый элемент не удаляется, второй элемент удаляется, если он меньше первого, третий — если он меньше предыдущего элемента, оставленного в массиве, и т. д. Например, массив 5.5, 2.5, 4.6, 7.2, 5.8, 9.4 должен быть преобразован к виду 5.5, 7.2, 9.4. Массив A и число N являются входными и выходными параметрами. С помощью этой процедуры преобразовать массивы A, B, C размера NA, NB, NC соответственно и вывести размер и содержимое полученных массивов.

Param10. Описать процедуру DoubleX(A, N, X), дублирующую в целочисленном массиве A размера N элементы, равные целому числу X. Массив A и число N являются входными и выходными параметрами. С помощью этой процедуры продублировать числа XA, XB, XC в массивах A, B, C размера NA, NB, NC соответственно и вывести размер и содержимое полученных массивов.

Param11. Описать процедуру SortArray(A, N), выполняющую сортировку по возрастанию вещественного массива A размера N. Массив A является входным и выходным параметром. С помощью этой процедуры отсортировать массивы A, B, C размера NA, NB, NC соответственно.

Param12. Описать процедуру SortIndex(A, N, I), формирующую для вещественного массива A размера N индексный массив I — массив целых чисел того же размера, содержащий номера элементов массива A в том порядке, который соответствует возрастанию элементов массива A (сам массив A при этом не изменяется). Индексный массив I является выходным параметром. С помощью этой процедуры создать индексные массивы для массивов A, B, C размера NA, NB, NC соответственно.

Param13. Описать процедуру Hill(A, N), меняющую порядок элементов вещественного массива A размера N на следующий: наименьший элемент массива располагается на первом месте, наименьший из оставшихся элементов — на последнем, следующий по величине располагается на втором месте, следующий — на предпоследнем и т. д. (в результате график значений элементов будет напоминать холм). Массив A является входным и выходным параметром. С помощью этой процедуры преобразовать массивы A, B, C размера NA, NB, NC соответственно.

Param14. Описать процедуру Split1(A, NA, B, NB, C, NC), формирующую по вещественному массиву A размера NA два вещественных массива B и C размера NB и NC соответственно; при этом массив B содержит все элементы массива A с нечетными порядковыми номерами (1, 3, …), а массив C — все элементы массива A с четными номерами (2, 4, …). Массивы B и C и числа NB и NC являются выходными параметрами. Применить эту процедуру к данному массиву A размера NA и вывести размер и содержимое полученных массивов B и C.

Param15. Описать процедуру Split2(A, NA, B, NB, C, NC), формирующую по целочисленному массиву A размера NA два целочисленных массива B и C размера NB и NC соответственно; при этом массив B содержит все четные числа из массива A, а массив C — все нечетные числа (в том же порядке). Массивы B и C и числа NB и NC являются выходными параметрами. Применить эту процедуру к данному массиву A размера NA и вывести размер и содержимое полученных массивов B и C.

Param16. Описать процедуру ArrayToMatrRow(A, K, M, N, B), формирующую по вещественному массиву A размера K матрицу B размера M × N (матрица заполняется элементами массива A по строкам). «Лишние» элементы массива игнорируются; если элементов массива недостаточно, то оставшиеся элементы матрицы полагаются равными 0. Двумерный массив B является выходным параметром. С помощью этой процедуры на основе данного массива A размера K и целых чисел M и N сформировать матрицу B размера M × N.

Param17. Описать процедуру ArrayToMatrCol(A, K, M, N, B), формирующую по вещественному массиву A размера K матрицу B размера M × N (матрица заполняется элементами массива A по столбцам). «Лишние» элементы массива игнорируются; если элементов массива недостаточно, то оставшиеся элементы матрицы полагаются равными 0. Двумерный массив B является выходным параметром. С помощью этой процедуры на основе данного массива A размера K и целых чисел M и N сформировать матрицу B размера M × N.

Param18. Описать процедуру Chessboard(M, N, A), формирующую по целым положительным числам M и N матрицу A размера M × N, которая содержит числа 0 и 1, расположенные в «шахматном» порядке, причем A1,1 = 0. Двумерный целочисленный массив A является выходным параметром. С помощью этой процедуры по данным целым числам M и N сформировать матрицу A размера M × N.

Param19. Описать функцию Norm1(A, M, N) вещественного типа, вычисляющую норму вещественной матрицы A размера M × N:

Norm1(A, M, N) = max {|A1,J| + |A2,J| + … + |AM,J|},

где максимум берется по всем J от 1 до N. Для данной матрицы A размера M × N найти Norm1(A, K, N), K = 1, …, M.

Param20. Описать функцию Norm2(A, M, N) вещественного типа, вычисляющую норму вещественной матрицы A размера M × N:

Norm2(A, M, N) = max {|AI,1| + |AI,2| + … + |AI,N|},

где максимум берется по всем I от 1 до M. Для данной матрицы A размера M × N найти Norm2(A, K, N), K = 1, …, M.

Param21. Описать функцию SumRow(A, M, N, K) вещественного типа, вычисляющую сумму элементов вещественной матрицы A размера M × N, расположенных в K-й строке (если K > M, то функция возвращает 0). Для данной матрицы A размера M × N и трех данных K найти SumRow(A, M, N, K).

Param22. Описать функцию SumCol(A, M, N, K) вещественного типа, вычисляющую сумму элементов вещественной матрицы A размера M × N, расположенных в K-м столбце (если K > N, то функция возвращает 0). Для данной матрицы A размера M × N и трех данных K найти SumCol(A, M, N, K).

Param23. Описать процедуру SwapRow(A, M, N, K1, K2), осуществляющую перемену местами строк вещественной матрицы A размера M × N с номерами K1 и K2. Матрица A является входным и выходным параметром; если K1 или K2 больше M, то матрица не изменяется. Используя эту процедуру, поменять для данной матрицы A размера M × N строки с данными номерами K1 и K2.

Param24. Описать процедуру SwapCol(A, M, N, K1, K2), осуществляющую перемену местами столбцов вещественной матрицы A размера M × N с номерами K1 и K2. Матрица A является входным и выходным параметром; если K1 или K2 больше N, то матрица не изменяется. Используя эту процедуру, поменять для данной матрицы A размера M × N столбцы с данными номерами K1 и K2.

Param25. Описать процедуру Transp(A, M), выполняющую транспонирование (т. е. зеркальное отражение относительно главной диагонали) квадратной вещественной матрицы A порядка M. Матрица A является входным и выходным параметром. Используя эту процедуру, транспонировать данную матрицу A порядка M.

Param26. Описать процедуру RemoveRows(A, M, N, K1, K2), удаляющую из вещественной матрицы A размера M × N строки с номерами от K1 до K2 включительно (предполагается, что 1 < K1 ≤ K2). Если K1 > M, то матрица не изменяется; если K2 > M, то удаляются строки матрицы с номерами от K1 до M. Двумерный массив A и числа M, N являются входными и выходными параметрами. Используя процедуру RemoveRows, удалить из данной матрицы A размера M × N строки с номерами от K1 до K2 и вывести размер полученной матрицы и ее элементы.

Param27. Описать процедуру RemoveCols(A, M, N, K1, K2), удаляющую из вещественной матрицы A размера M × N столбцы с номерами от K1 до K2 включительно (предполагается, что 1 < K1 ≤ K2). Если K1 > N, то матрица не изменяется; если K2 > N, то удаляются столбцы матрицы с номерами от K1 до N. Двумерный массив A и числа M, N являются входными и выходными параметрами. Используя процедуру RemoveCols, удалить из данной матрицы A размера M × N столбцы с номерами от K1 до K2 и вывести размер полученной матрицы и ее элементы.

Param28. Описать процедуру RemoveRowCol(A, M, N, K, L), удаляющую из вещественной матрицы A размера M × N строку и столбец, которые содержат элемент AK,L (предполагается, что M > 1 и N > 1; если K > M или L > N, то матрица не изменяется). Двумерный массив A и числа M, N являются входными и выходными параметрами. Дана матрица A размера M × N и числа K, L. Применить к матрице A процедуру RemoveRowCol и вывести размер полученной матрицы и ее элементы.

Param29. Описать процедуру SortCols(A, M, N), выполняющую сортировку по возрастанию столбцов целочисленной матрицы A размера M × N (столбцы сравниваются лексикографически: если первые элементы столбцов различны, то меньшим считается столбец, содержащий меньший первый элемент; если первые элементы столбцов равны, то анализируются их вторые элементы и т. д.). Двумерный массив A является входным и выходным параметром. Используя процедуру SortCols, отсортировать столбцы данной матрицы A размера M × N.

Процедуры и функции: работа со строками

Param30. Описать функцию IsIdent(S) целого типа, проверяющую, является ли строка S допустимым идентификатором, т. е. непустой строкой, которая содержит только латинские буквы, цифры и символ подчеркивания «_» и не начинается с цифры. Если S является допустимым идентификатором, то функция возвращает 0. Если S является пустой строкой, то возвращается −1, если S начинается с цифры, то возвращается −2. Если S содержит недопустимые символы, то возвращается номер первого недопустимого символа. Проверить с помощью функции IsIdent пять данных строк.

Param31. Описать функцию FillStr(S, N) строкового типа, возвращающую строку длины N, заполненную повторяющимися копиями строки-шаблона S (последняя копия строки-шаблона может входить в результирующую строку частично). Используя эту функцию, сформировать по данному числу N и пяти данным строкам-шаблонам пять результирующих строк длины N.

Param32. Описать процедуру UpCaseRus(S), преобразующую все строчные русские буквы строки S в прописные (остальные символы строки S не изменяются). Строка S является входным и выходным параметром. Используя процедуру UpCaseRus, преобразовать пять данных строк.

Param33. Описать процедуру LowCaseRus(S), преобразующую все прописные русские буквы строки S в строчные (остальные символы строки S не изменяются). Строка S является входным и выходным параметром. Используя процедуру LowCaseRus, преобразовать пять данных строк.

Param34. Описать процедуру TrimLeftC(S, C), удаляющую в строке S начальные символы, совпадающие с символом C. Строка S является входным и выходным параметром. Дан символ C и пять строк. Используя процедуру TrimLeftC, преобразовать данные строки.

Param35. Описать процедуру TrimRightC(S, C), удаляющую в строке S конечные символы, совпадающие с символом C. Строка S является входным и выходным параметром. Дан символ C и пять строк. Используя процедуру TrimRightC, преобразовать данные строки.

Param36. Описать функцию InvStr(S, K, N) строкового типа, возвращающую инвертированную подстроку строки S, содержащую в обратном порядке N символов строки S, начиная с ee K-го символа. Если K превосходит длину строки S, то возвращается пустая строка; если длина строки меньше K + N, то инвертируются все символы строки, начиная с ee K-го символа. Вывести значения функции InvStr для данной строки S и каждой из трех пар положительных целых чисел: (K1, N1), (K2, N2), (K3, N3).

Param37. Описать функцию PosSub(S0, S, K, N) целого типа, возвращающую номер позиции, начиная с которой в строке S содержится первое вхождение строки S0, причем анализируются только N символов строки S, начиная с ее K-го символа (таким образом, PosSub обеспечивает поиск в подстроке). Если K превосходит длину строки S, то возвращается 0, если длина строки меньше K + N, то анализируются все символы строки, начиная с ее K-го символа. Если в требуемой подстроке строки S вхождения S0 отсутствуют, то функция возвращает 0. Вывести значения функции PosSub для данных строк S0, S и каждой из трех пар положительных целых чисел: (K1, N1), (K2, N2), (K3, N3).

Param38. Описать функцию PosLast(S0, S) целого типа, возвращающую номер позиции, начиная с которой в строке S содержится последнее вхождение подстроки S0. Если в строке S отсутствуют подстроки S0, то функция возвращает 0. Вывести значения этой функции для пяти данных пар строк S0 и S.

Param39. Описать функцию PosK(S0, S, K) целого типа, возвращающую номер позиции, начиная с которой в строке S содержится K-е вхождение подстроки S0 (K > 0). Если количество вхождений S0 в строке S меньше K, то функция возвращает 0. Считать, что перекрывающихся вхождений подстрок S0 строка S не содержит. Вывести значения этой функции для пяти данных троек: S0, S и K.

Param40. Описать функцию WordK(S, K) строкового типа, возвращающую K-е слово строки S (словом считается набор символов, не содержащий пробелов и ограниченный пробелами или началом/концом строки). Если количество слов в строке меньше K, то функция возвращает пустую строку. Используя эту функцию, выделить из данной строки S слова с данными номерами K1, K2, K3.

Param41. Описать процедуру SplitStr(S, W, N), которая формирует по данной строке S массив W слов, входящих в S (массив W и его размер N являются выходными параметрами). Словом считается набор символов, не содержащий пробелов и ограниченный пробелами или началом/концом строки; предполагается, что строка S содержит не более 10 слов. Используя функцию SplitStr, найти количество слов N, содержащихся в данной строке S, и сами эти слова.

Param42. Описать функцию CompressStr(S) строкового типа, выполняющую сжатие строки S по следующему правилу: каждая подстрока строки S, состоящая из более чем четырех одинаковых символов C, заменяется текстом вида «С{K}», где K — количество символов C (предполагается, что строка S не содержит фигурных скобок «{» и «}»). Например, для строки S = «bbbccccce» функция вернет строку «bbbc{5}e». С помощью функции CompressStr сжать пять данных строк.

Param43. Описать функцию DecompressStr(S) строкового типа, восстанавливающую строку, сжатую функцией CompressStr (см. задание Param42). Параметр S содержит сжатую строку; восстановленная строка является возвращаемым значением функции. С помощью функции DecompressStr восстановить пять данных сжатых строк.

Param44. Описать функцию DecToBin(N) строкового типа, возвращающую строковое представление целого неотрицательного числа N в двоичной системе счисления. Результирующая строка состоит из символов «0»–«1» и не содержит ведущих нулей (за исключением представления числа 0). Используя эту функцию, получить двоичные представления пяти данных чисел.

Param45. Описать функцию DecToHex(N) строкового типа, возвращающую строковое представление целого неотрицательного числа N в 16-ричной системе счисления. Результирующая строка состоит из символов «0»–«9», «A»–«F» и не содержит ведущих нулей (за исключением представления числа 0). Используя эту функцию, получить 16-ричные представления пяти данных чисел.

Param46. Описать функцию BinToDec(S) целого типа, определяющую целое неотрицательное число по его строковому представлению S в двоичной системе счисления. Параметр S имеет строковый тип, состоит из символов «0»–«1» и не содержит ведущих нулей (за исключением значения «0»). Используя эту функцию, вывести пять чисел, для которых даны их двоичные представления.

Param47. Описать функцию HexToDec(S) целого типа, определяющую целое неотрицательное число по его строковому представлению S в 16-ричной системе счисления. Параметр S имеет строковый тип, состоит из символов «0»–«9», «A»–«F» и не содержит ведущих нулей (за исключением значения «0»). Используя эту функцию, вывести пять чисел, для которых даны их 16-ричные представления.

Процедуры и функции: работа с файлами

Param48. Описать функцию IntFileSize(S) целого типа, возвращающую количество элементов в файле целых чисел с именем S. Если файл не существует, то функция возвращает −1. С помощью этой функции найти количество элементов в трех файлах с данными именами.

Param49. Описать функцию LineCount(S) целого типа, возвращающую количество строк в текстовом файле с именем S. Если файл не существует, то функция возвращает −1. С помощью этой функции найти количество строк в трех файлах с данными именами.

Param50. Описать процедуру InvIntFile(S), меняющую порядок следования элементов файла целого типа с именем S на обратный. Если файл не существует или содержит менее двух элементов, то процедура не выполняет никаких действий. Обработать с помощью этой процедуры три файла с данными именами.

Param51. Описать процедуру AddLineNumbers(S, N, K, L), добавляющую в начало каждой строки существующего текстового файла с именем S ее порядковый номер: первая строка получает номер N, вторая — N + 1 и т. д. Номер отображается в K позициях, выравнивается по правому краю и отделяется от последующего текста L пробелами (K > 0, L > 0). Если строка файла является пустой, то она также нумеруется, но пробелы после номера не добавляются. Применить эту процедуру к данному файлу, используя указанные значения N, K и L.

Param52. Описать процедуру RemoveLineNumbers(S), удаляющую из начала каждой строки существующего текстового файла с именем S ее порядковый номер, а также пробелы, отделяющие номер от последующего текста (предполагается, что номера могли быть ранее добавлены к строкам файла с помощью процедуры AddLineNumbers — см. задание Param51). Если строки не содержат номеров, то процедура не выполняет никаких действий. Применить эту процедуру к файлу с данным именем.

Param53. Описать процедуру SplitIntFile(S0, K, S1, S2), копирующую первые K (≥ 0) элементов существующего файла целых чисел с именем S0 в новый файл целых чисел с именем S1, a остальные элементы — в новый файл целых чисел с именем S2. Один из созданных файлов может остаться пустым. Применить эту процедуру к файлу с данным именем S0, используя указанные значения K, S1 и S2.

Param54. Описать процедуру SplitText(S0, K, S1, S2), копирующую первые K (≥ 0) строк существующего текстового файла с именем S0 в новый текстовый файл с именем S1, a остальные строки — в новый текстовый файл с именем S2. Один из созданных файлов может остаться пустым. Применить эту процедуру к файлу с данным именем S0, используя указанные значения K, S1 и S2.

Param55. Описать процедуру StringFileToText(S), преобразующую двоичный строковый файл с именем S в текстовый файл с тем же именем. Используя эту процедуру, преобразовать два данных строковых файла с именами S1 и S2 в текстовые.

Param56. Описать процедуру TextToStringFile(S), преобразующую текстовый файл с именем S в двоичный строковый файл с тем же именем. Используя эту процедуру, преобразовать два данных текстовых файла с именами S1 и S2 в строковые.

Param57. Описать процедуру EncodeText(S, K), которая шифрует текстовый файл с именем S, выполняя циклическую замену каждой русской буквы на букву того же регистра, расположенную в алфавите на K-й позиции после шифруемой буквы (0 < K < 10). Например, при K = 3 «А» перейдет в «Г», «я» — в «в». Букву «ё» в алфавите не учитывать, считая, что за буквой «е» сразу идет «ж». Символы, не являющиеся русскими буквами, при шифровании не изменять. Используя эту процедуру и зная кодовое смещение K, зашифровать файл с указанным именем.

Param58. Описать процедуру DecodeText(S, K), которая дешифрует текстовый файл с именем S, зашифрованный с использованием кодового смещения K (способ шифрования описан в задании Param57). Используя эту процедуру и зная кодовое смещение K, расшифровать файл с указанным именем.

Процедуры и функции: работа с записями

При вводе и выводе каждой даты вначале указывается день, затем номер месяца, затем год.

При вводе каждой точки на плоскости вначале указывается ее абсцисса (x-координата), затем ее ордината (y-координата).

Param59. Описать тип TDate — запись с полями целого типа Day (день), Month (месяц) и Year (год) — и функцию LeapYear(D) логического типа с параметром типа TDate, которая возвращает True, если год в дате D является високосным, и False в противном случае. Вывести значение функции LeapYear для пяти данных дат (предполагается, что все даты являются правильными). Високосным считается год, делящийся на 4, за исключением тех годов, которые делятся на 100 и не делятся на 400.

Param60. Используя тип TDate и функцию LeapYear (см. задание Param59), описать функцию DaysInMonth(D) целого типа с параметром типа TDate, которая возвращает количество дней для месяца, указанного в дате D. Вывести значение функции DaysInMonth для пяти данных дат (предполагается, что все даты являются правильными).

Param61. Используя тип TDate и функцию DaysInMonth (см. задания Param59 и Param60), описать функцию CheckDate(D) целого типа с параметром типа TDate, которая проверяет правильность даты, указанной в параметре D. Если дата D является правильной, то функция возвращает 0; если в дате указан неверный номер месяца, то функция возвращает 1; если в дате указан неверный день для допустимого месяца, то возвращается 2. Вывести значение функции CheckDate для пяти данных дат.

Param62. Используя тип TDate и функции DaysInMonth и CheckDate (см. задания Param59−Param61), описать процедуру PrevDate(D) с параметром типа TDate, которая преобразует дату D к предыдущей дате (если дата D является неправильной, то она не изменяется). Запись D является входным и выходным параметром. Применить процедуру PrevDate к пяти данным датам.

Param63. Используя тип TDate и функции DaysInMonth и CheckDate (см. задания Param59−Param61), описать процедуру NextDate(D) с параметром типа TDate, которая преобразует дату D к следующей дате (если дата D является неправильной, то она не изменяется). Запись D является входным и выходным параметром. Применить процедуру NextDate к пяти данным датам.

Param64. Описать тип TPoint — запись с полями вещественного типа X и Y (координаты точки на плоскости) — и функцию Leng(A, B) вещественного типа, находящую длину отрезка AB на плоскости по координатам его концов:

|AB| = ((A.X − B.X)2 + (A.Y − B.Y)2)1/2

(A и B — параметры типа TPoint). С помощью этой функции найти длины отрезков AB, AC, AD, если даны координаты точек A, B, C, D.

Param65. Используя тип TPoint и функцию Leng (см. задание Param64), описать тип TTriangle — запись с полями A, B, C типа TPoint (вершины треугольника) — и функцию Perim(T) вещественного типа, находящую периметр треугольника T (T — параметр типа TTriangle). С помощью этой функции найти периметры треугольников ABC, ABD, ACD, если даны координаты точек A, B, C, D.

Param66. Используя типы TPoint, TTriangle и функции Leng и Perim (см. задания Param64 и Param65), описать функцию Area(T) вещественного типа, находящую площадь треугольника T (T — параметр типа TTriangle) по формуле Герона:

SABC = (p·(p − |AB|)·(p − |AC|)·(p − |BC|))1/2,

где p — полупериметр. С помощью этой функции найти площади треугольников ABC, ABD, ACD, если даны координаты точек A, B, C, D.

Param67. Используя типы TPoint, TTriangle и функции Leng и Area (см. задания Param64–Param66), описать функцию Dist(P, A, B) вещественного типа (P, A, B — параметры типа TPoint), находящую расстояние D(P, AB) от точки P до прямой AB по формуле

D(P, AB) = 2·SPAB/|AB|,

где SPAB — площадь треугольника PAB. С помощью этой функции найти расстояния от точки P до прямых AB, AC, BC, если даны координаты точек P, A, B, C.

Param68. Используя типы TPoint, TTriangle и функцию Dist (см. задания Param64, Param65, Param67), описать процедуру Altitudes(T, h1, h2, h3), находящую высоты h1, h2, h3 треугольника T (T — входной параметр типа TTriangle, h1, h2, h3 — выходные вещественные параметры), проведенные соответственно из вершин T.A, T.B, T.C. С помощью этой процедуры найти высоты треугольников ABC, ABD, ACD, если даны координаты точек A, B, C, D.

Param69. Используя тип TPoint и функцию Leng (см. задание Param64), описать функцию PerimN(P, N) вещественного типа, находящую периметр N-угольника, вершины которого (в порядке их обхода) передаются в массиве P размера N (> 2) с элементами типа TPoint. С помощью этой функции найти периметры трех многоугольников, если дано число их сторон и координаты их вершин.

Param70. Используя типы TPoint, TTriangle и функцию Area (см. задания Param64–Param66), описать функцию AreaN(P, N) вещественного типа, находящую площадь выпуклого N-угольника, вершины которого (в порядке их обхода) передаются в массиве P размера N (> 2) с элементами типа TPoint. С помощью этой функции найти площади трех многоугольников, если дано число их сторон и координаты их вершин.


Группы заданий

Рекурсия: группа Recur

Рекурсия: простейшие алгоритмы

Задания этой подгруппы можно легко решить и без использования рекурсии. Данное обстоятельство связано с тем, что в заданиях рассматриваются простейшие примеры рекурсии, легко сводимые к итерационным алгоритмам. Более того, в некоторых случаях непосредственные вычисления по рекурсивным формулам оказываются весьма неэффективными. Однако именно на подобных примерах проще всего получить первоначальные навыки разработки рекурсивных алгоритмов.

Recur1. Описать рекурсивную функцию Fact(N) вещественного типа, вычисляющую значение факториала

N! = 1·2·…·N

(N > 0 — параметр целого типа). С помощью этой функции вычислить факториалы пяти данных чисел.

Recur2. Описать рекурсивную функцию Fact2(N) вещественного типа, вычисляющую значение двойного факториала

N!! = N·(N−2)·(N−4)·…

(N > 0 — параметр целого типа; последний сомножитель в произведении равен 2, если N — четное число, и 1, если N — нечетное). С помощью этой функции вычислить двойные факториалы пяти данных чисел.

Recur3. Описать рекурсивную функцию PowerN(X, N) вещественного типа, находящую значение N-й степени числа X по формулам:

X 0 = 1,
X N = (X N/2)2 при четных N > 0, X N = X·X N−1 при нечетных N > 0,
X N = 1/X −N при N < 0

(X ≠ 0 — вещественное число, N — целое; в формуле для четных N должна использоваться операция целочисленного деления). С помощью этой функции найти значения X N для данного X при пяти данных значениях N.

Recur4. Описать рекурсивную функцию Fib1(N) целого типа, вычисляющую N-й элемент последовательности чисел Фибоначчи (N — целое число):

F1 = F2 = 1, FK = FK−2 + FK−1, K = 3, 4, … .

С помощью этой функции найти пять чисел Фибоначчи с данными номерами, и вывести эти числа вместе с количеством рекурсивных вызовов функции Fib1, потребовавшихся для их нахождения.

Recur5. Описать рекурсивную функцию Fib2(N) целого типа, вычисляющую N-й элемент последовательности чисел Фибоначчи (N — целое число):

F1 = F2 = 1, FK = FK−2 + FK−1, K = 3, 4, … .

Считать, что номер N не превосходит 20. Для уменьшения количества рекурсивных вызовов по сравнению с функцией Fib1 (см. задание Recur4) создать вспомогательный массив для хранения уже вычисленных чисел Фибоначчи и обращаться к нему при выполнении функции Fib2. С помощью функции Fib2 найти пять чисел Фибоначчи с данными номерами.

Recur6. Описать рекурсивную функцию Combin1(N, K) целого типа, находящую C(N, K) — число сочетаний из N элементов по K — с помощью рекуррентного соотношения:

C(N, 0) = C(N, N) = 1,
C(N, K) = C(N − 1, K) + C(N − 1, K − 1) при 0 < K < N.

Параметры функции — целые числа; N > 0, 0 ≤ K ≤ N. Дано число N и пять различных значений K. Вывести числа C(N, K) вместе с количеством рекурсивных вызовов функции Combin1, потребовавшихся для их нахождения.

Recur7. Описать рекурсивную функцию Combin2(N, K) целого типа, находящую C(N, K) — число сочетаний из N элементов по K — с помощью рекуррентного соотношения:

C(N, 0) = C(N, N) = 1,
C(N, K) = C(N − 1, K) + C(N − 1, K − 1) при 0 < K < N.

Параметры функции — целые числа; N > 0, 0 ≤ K ≤ N. Считать, что параметр N не превосходит 20. Для уменьшения количества рекурсивных вызовов по сравнению с функцией Combin1 (см. задание Recur6) описать вспомогательный двумерный массив для хранения уже вычисленных чисел C(N, K) и обращаться к нему при выполнении функции Combin2. С помощью функции Combin2 найти числа C(N, K) для данного значения N и пяти различных значений K.

Recur8. Описать рекурсивную функцию RootK(X, K, N) вещественного типа, находящую приближенное значение корня K-й степени из числа X по формуле:

Y0 = 1, YN+1 = YN − (YN − X/(YN)K−1)/K,

где YN обозначает RootK(X, K, N) при фиксированных X и K. Параметры функции: X (> 0) — вещественное число, K (> 1) и N (> 0) — целые. С помощью функции RootK найти для данного числа X приближенные значения его корня K-й степени при шести данных значениях N.

Recur9. Описать рекурсивную функцию GCD(A, B) целого типа, находящую наибольший общий делитель (НОД, greatest common divisor) двух целых положительных чисел A и B, используя алгоритм Евклида:

НОД(A, B) = НОД(B, A mod B), B ≠ 0; НОД(A, 0) = A,

где «mod» обозначает операцию взятия остатка от деления. С помощью этой функции найти НОД(A, B), НОД(A, C), НОД(A, D), если даны числа A, B, C, D.

Recur10. Описать рекурсивную функцию DigitSum(K) целого типа, которая находит сумму цифр целого числа K, не используя оператор цикла. С помощью этой функции найти суммы цифр для пяти данных целых чисел.

Recur11. Описать рекурсивную функцию MaxElem(A, N) целого типа, которая находит максимальный элемент целочисленного массива A размера N (1 ≤ N ≤ 10), не используя оператор цикла. С помощью этой функции найти максимальные элементы массивов A, B, C размера NA, NB, NC соответственно.

Recur12. Описать рекурсивную функцию DigitCount(S) целого типа, которая находит количество цифр в строке S, не используя оператор цикла. С помощью этой функции найти количество цифр в каждой из пяти данных строк.

Recur13. Описать рекурсивную функцию Palindrome(S) логического типа, возвращающую True, если строка S является палиндромом (т. е. читается одинаково слева направо и справа налево), и False в противном случае. Оператор цикла в теле функции не использовать. Вывести значения функции Palindrome для пяти данных строк.

Рекурсия: разбор выражений

Во всех заданиях данной подгруппы предполагается, что исходные строки, определяющие выражения, не содержат пробелов.

При выполнении заданий не следует использовать оператор цикла.

Recur14. Вывести значение целочисленного выражения, заданного в виде строки S. Выражение определяется следующим образом:

<выражение> | ::= | <цифра> | <выражение> + <цифра> |
 |  | <выражение> − <цифра>

Recur15. Вывести значение целочисленного выражения, заданного в виде строки S. Выражение определяется следующим образом:

<выражение> | ::= | <терм> | <выражение> + <терм> |
 |  | <выражение> − <терм>
<терм> | ::= | <цифра> | <терм> * <цифра>

Recur16. Вывести значение целочисленного выражения, заданного в виде строки S. Выражение определяется следующим образом:

<выражение> | ::= | <терм> | <выражение> + <терм> |
 |  | <выражение> − <терм>
<терм> | ::= | <элемент> | <терм> * <элемент>
<элемент> | ::= | <цифра> | (<выражение>)

Recur17. Вывести значение целочисленного выражения, заданного в виде строки S. Выражение определяется следующим образом:

<выражение> | ::= | <цифра> |
 |  | (<выражение><знак><выражение>)
<знак> | ::= | + | − | *

Recur18. Проверить правильность выражения, заданного в виде непустой строки S (выражение определяется по тем же правилам, что и в задании Recur17). Если выражение составлено правильно, то вывести True, иначе вывести False.

Recur19. Проверить правильность выражения, заданного в виде непустой строки S (выражение определяется по тем же правилам, что и в задании Recur17). Если выражение составлено правильно, то вывести 0, в противном случае вывести номер первого ошибочного, лишнего или недостающего символа в строке S.

Recur20. Вывести значение целочисленного выражения, заданного в виде строки S. Выражение определяется следующим образом (функция M возвращает максимальный из своих параметров, а функция m — минимальный):

<выражение> | ::= | <цифра> | M(<выражение> , <выражение>) |
 |  | m(<выражение> , <выражение>)

Recur21. Вывести значение логического выражения, заданного в виде строки S. Выражение определяется следующим образом («T» — True, «F» — False):

<выражение> | ::= | T | F | And(<выражение> , <выражение>) |
 |  | Or(<выражение> , <выражение>)

Recur22. Вывести значение целочисленного выражения, заданного в виде строки S. Выражение определяется следующим образом (функция M возвращает максимальный из своих параметров, а функция m — минимальный):

<выражение> | ::= | <цифра> | M(<параметры>) | m(<параметры>)
<параметры> | ::= | <выражение> | <выражение> , <параметры>

Recur23. Вывести значение логического выражения, заданного в виде строки S. Выражение определяется следующим образом («T» — True, «F» — False):

<выражение> | ::= | T | F | And(<параметры>) | Or(<параметры>)
<параметры> | ::= | <выражение> | <выражение> , <параметры>

Recur24. Вывести значение логического выражения, заданного в виде строки S. Выражение определяется следующим образом («T» — True, «F» — False):

<выражение> | ::= | T | F | And(<параметры>) |
 |  | Or(<параметры>) | Not(<выражение>)
<параметры> | ::= | <выражение> | <выражение> , <параметры>

Рекурсия: перебор с возвратом

Recur25. Дано дерево глубины N, каждая внутренняя вершина которого имеет K (< 10) непосредственных потомков (нумеруются от 1 до K). Корень дерева имеет номер 0. Записать в текстовый файл с данным именем все возможные пути, ведущие от корня к листьям. Перебирать пути, начиная с «самого левого» и заканчивая «самым правым» (при этом первыми заменять конечные элементы пути).

Recur26. Дано дерево глубины N, каждая внутренняя вершина которого имеет K (< 10) непосредственных потомков (нумеруются от 1 до K). Корень дерева имеет номер 0. Записать в текстовый файл с данным именем все пути, ведущие от корня к листьям и удовлетворяющие следующему условию: никакие соседние элементы пути не нумеруются одной и той же цифрой. Порядок перебора путей такой же, как в задании Recur25.

Recur27. Дано дерево глубины N (N — четное), каждая внутренняя вершина которого имеет 2 непосредственных потомка: A с весом 1 и B с весом −1. Корень дерева C имеет вес 0. Записать в текстовый файл с данным именем все пути от корня к листьям, удовлетворяющие следующему условию: суммарный вес элементов пути равен 0. Порядок перебора путей такой же, как в задании Recur25.

Recur28. Дано дерево глубины N того же типа, что и в задании Recur27. Записать в текстовый файл с данным именем все пути от корня к листьям, удовлетворяющие следующему условию: суммарный вес элементов для любого начального отрезка пути неотрицателен. Порядок перебора путей такой же, как в задании Recur25.

Recur29. Дано дерево глубины N, каждая внутренняя вершина которого имеет 3 непосредственных потомка: A с весом 1, B с весом 0 и C с весом −1. Корень дерева D имеет вес 0. Записать в текстовый файл с данным именем все пути от корня к листьям, удовлетворяющие следующим условиям: суммарный вес элементов для любого начального отрезка пути неположителен, а суммарный вес всех элементов пути равен 0. Порядок перебора путей такой же, как в задании Recur25.

Recur30. Дано дерево глубины N того же типа, что и в задании Recur29. Записать в текстовый файл с данным именем все пути от корня к листьям, удовлетворяющие следующим условиям: никакие соседние элементы пути не обозначаются одной и той же буквой, а суммарный вес всех элементов пути равен 0. Порядок перебора путей такой же, как в задании Recur25.


Группы заданий

Динамические структуры данных: группа Dynamic

Все числа, используемые в заданиях на динамические структуры данных, являются целыми. Все указатели имеют тип PNode и указывают на записи типа TNode; типы PNode и TNode определены в задачнике Programming Taskbook. В заданиях данной группы используются поля Data, Next и Prev записей типа TNode, поэтому при выполнении этих заданий можно считать, что типы PNode и TNode описаны следующим образом:

[Pascal]

type
PNode = ^TNode;
TNode = record
Data: integer;
Next: PNode;
Prev: PNode;
end;

[C++]

struct TNode
{
int Data;
TNode* Next;
TNode* Prev;
};
typedef TNode* PNode;

Во вводных заданиях, а также в заданиях на стек и очередь при работе с записями типа TNode используются только поля Data и Next; в заданиях на списки используются все поля записи TNode.

Так как переменные типа «указатель» предназначены для хранения адресов, в формулировках заданий слова «указатель» (на элемент данных) и «адрес» (элемента данных) используются как синонимы.

В заданиях, в которых идет речь о номерах элементов списка, предполагается, что элементы списка нумеруются от 1.

В программах на языке C++ для освобождения динамической памяти, связанной с указателем p типа PNode, следует использовать функцию DeleteNode(p).

Динамические структуры данных: узлы и цепочки узлов

Dynamic1. Дан адрес P1 записи типа TNode, содержащей поле Data (целого типа) и поле Next (типа PNode — указателя на TNode). Эта запись связана полем Next со следующей записью того же типа. Вывести значения полей Data обеих записей, а также адрес P2 следующей записи.

Dynamic2. Дан адрес P1 записи типа TNode. Эта запись связана полем Next со следующей записью того же типа, она, в свою очередь, — со следующей, и так далее до записи, поле Next которой равно nil (таким образом, возникает цепочка связанных записей). Вывести значения полей Data для всех элементов цепочки, длину цепочки (т. е. число ее элементов) и адрес ее последнего элемента.

Динамические структуры данных: стек

В заданиях данной подгруппы структура «стек» (stack) моделируется цепочкой связанных узлов-записей типа TNode. Поле Next последнего элемента цепочки равно nil. Вершиной стека (top) считается первый элемент цепочки. Для доступа к стеку используется указатель на его вершину (для пустого стека данный указатель полагается равным nil). Значением элемента стека считается значение его поля Data.

Dynamic3. Дано число D и указатель P1 на вершину непустого стека. Добавить элемент со значением D в стек и вывести адрес P2 новой вершины стека.

Dynamic4. Дано число N (> 0) и набор из N чисел. Создать стек, содержащий исходные числа (последнее число будет вершиной стека), и вывести указатель на его вершину.

Dynamic5. Дан указатель P1 на вершину непустого стека. Извлечь из стека первый (верхний) элемент и вывести его значение D, а также адрес P2 новой вершины стека. Если после извлечения элемента стек окажется пустым, то положить P2 = nil. После извлечения элемента из стека освободить память, занимаемую этим элементом.

Dynamic6. Дан указатель P1 на вершину стека, содержащего не менее десяти элементов. Извлечь из стека первые девять элементов и вывести их значения. Вывести также адрес новой вершины стека. После извлечения элементов из стека освобождать память, которую они занимали.

Dynamic7. Дан указатель P1 на вершину стека (если стек пуст, то P1 = nil). Извлечь из стека все элементы и вывести их значения. Вывести также количество извлеченных элементов N (для пустого стека вывести 0). После извлечения элементов из стека освобождать память, которую они занимали.

Dynamic8. Даны указатели P1 и P2 на вершины двух непустых стеков. Переместить все элементы из первого стека во второй (в результате элементы первого стека будут располагаться во втором стеке в порядке, обратном исходному) и вывести адрес новой вершины второго стека. Операции выделения и освобождения памяти не использовать.

Dynamic9. Даны указатели P1 и P2 на вершины двух непустых стеков. Перемещать элементы из первого стека во второй, пока значение вершины первого стека не станет четным (перемещенные элементы первого стека будут располагаться во втором стеке в порядке, обратном исходному). Если в первом стеке нет элементов с четными значениями, то переместить из первого стека во второй все элементы. Вывести адреса новых вершин первого и второго стека (если первый стек окажется пустым, то вывести для него константу nil). Операции выделения и освобождения памяти не использовать.

Dynamic10. Дан указатель P1 на вершину непустого стека. Создать два новых стека, переместив в первый из них все элементы исходного стека с четными значениями, а во второй — с нечетными (элементы в новых стеках будут располагаться в порядке, обратном исходному; один из этих стеков может оказаться пустым). Вывести адреса вершин полученных стеков (для пустого стека вывести nil). Операции выделения и освобождения памяти не использовать.

Dynamic11. Дан указатель P1 на вершину стека (если стек пуст, то P1 = nil). Также дано число N (> 0) и набор из N чисел. Описать тип TStack — запись с одним полем Top типа PNode (поле указывает на вершину стека) — и процедуру Push(S, D), которая добавляет в стек S новый элемент со значением D (S — входной и выходной параметр типа TStack, D — входной параметр целого типа). С помощью процедуры Push добавить в исходный стек данный набор чисел (последнее число будет вершиной стека) и вывести адрес новой вершины стека.

Dynamic12. Дан указатель P1 на вершину стека, содержащего не менее пяти элементов. Используя тип TStack (см. задание Dynamic11), описать функцию Pop(S) целого типа, которая извлекает из стека S первый (верхний) элемент, возвращает его значение и освобождает память, которую занимал извлеченный элемент (S — входной и выходной параметр типа TStack). С помощью функции Pop извлечь из исходного стека пять элементов и вывести их значения. Вывести также указатель на новую вершину стека (если результирующий стек окажется пустым, то этот указатель должен быть равен nil).

Dynamic13. Дан указатель P1 на вершину стека. Используя тип TStack (см. задание Dynamic11), описать функции StackIsEmpty(S) логического типа (возвращает True, если стек S пуст, и False в противном случае) и Peek(S) целого типа (возвращает значение вершины непустого стека S, не удаляя ее из стека). В обеих функциях переменная S является входным параметром типа TStack. С помощью этих функций, а также функции Pop из задания Dynamic12, извлечь из исходного стека пять элементов (или все содержащиеся в нем элементы, если их менее пяти) и вывести их значения. Вывести также значение функции StackIsEmpty для результирующего стека и, если результирующий стек не является пустым, значение и адрес его новой вершины.

Динамические структуры данных: очередь

В заданиях данной подгруппы структура «очередь» (queue) моделируется цепочкой связанных узлов-записей типа TNode. Поле Next последнего элемента цепочки равно nil. Началом очереди («головой», head) считается первый элемент цепочки, концом («хвостом», tail) — ее последний элемент. Для возможности быстрого добавления в конец очереди нового элемента удобно хранить, помимо указателя на начало очереди, также и указатель на ее конец. В случае пустой очереди указатели на ее начало и конец полагаются равными nil. Как и для стека, значением элемента очереди считается значение его поля Data.

Dynamic14. Дан набор из 10 чисел. Создать очередь, содержащую данные числа в указанном порядке (первое число будет размещаться в начале очереди, последнее — в конце), и вывести указатели P1 и P2 на начало и конец очереди.

Dynamic15. Дан набор из 10 чисел. Создать две очереди: первая должна содержать числа из исходного набора с нечетными номерами (1, 3, …, 9), а вторая — с четными (2, 4, …, 10); порядок чисел в каждой очереди должен совпадать с порядком чисел в исходном наборе. Вывести указатели на начало и конец первой, а затем второй очереди.

Dynamic16. Дан набор из 10 чисел. Создать две очереди: первая должна содержать все нечетные, а вторая — все четные числа из исходного набора (порядок чисел в каждой очереди должен совпадать с порядком чисел в исходном наборе). Вывести указатели на начало и конец первой, а затем второй очереди (одна из очередей может оказаться пустой; в этом случае вывести для нее две константы nil).

Dynamic17. Дано число D и указатели P1 и P2 на начало и конец очереди (если очередь является пустой, то P1 = P2 = nil). Добавить элемент со значением D в конец очереди и вывести новые адреса начала и конца очереди.

Dynamic18. Дано число D и указатели P1 и P2 на начало и конец очереди, содержащей не менее двух элементов. Добавить элемент со значением D в конец очереди и извлечь из очереди первый (начальный) элемент. Вывести значение извлеченного элемента и новые адреса начала и конца очереди. После извлечения элемента из очереди освободить память, занимаемую этим элементом.

Dynamic19. Дано число N (> 0) и указатели P1 и P2 на начало и конец непустой очереди. Извлечь из очереди N начальных элементов и вывести их значения (если очередь содержит менее N элементов, то извлечь все ее элементы). Вывести также новые адреса начала и конца очереди (для пустой очереди дважды вывести nil). После извлечения элементов из очереди освобождать память, которую они занимали.

Dynamic20. Даны указатели P1 и P2 на начало и конец непустой очереди. Извлекать из очереди элементы, пока значение начального элемента очереди не станет четным, и выводить значения извлеченных элементов (если очередь не содержит элементов с четными значениями, то извлечь все ее элементы). Вывести также новые адреса начала и конца очереди (для пустой очереди дважды вывести nil). После извлечения элементов из очереди освобождать память, которую они занимали.

Dynamic21. Даны две очереди; адреса начала и конца первой равны P1 и P2, а второй — P3 и P4 (если очередь является пустой, то соответствующие адреса равны nil). Переместить все элементы первой очереди (в порядке от начала к концу) в конец второй очереди и вывести новые адреса начала и конца второй очереди. Операции выделения и освобождения памяти не использовать.

Dynamic22. Дано число N (> 0) и две непустые очереди; адреса начала и конца первой равны P1 и P2, а второй — P3 и P4. Переместить N начальных элементов первой очереди в конец второй очереди. Если первая очередь содержит менее N элементов, то переместить из первой очереди во вторую все элементы. Вывести новые адреса начала и конца первой, а затем второй очереди (для пустой очереди дважды вывести nil). Операции выделения и освобождения памяти не использовать.

Dynamic23. Даны две непустые очереди; адреса начала и конца первой равны P1 и P2, а второй — P3 и P4. Перемещать элементы из начала первой очереди в конец второй, пока значение начального элемента первой очереди не станет четным (если первая очередь не содержит четных элементов, то переместить из первой очереди во вторую все элементы). Вывести новые адреса начала и конца первой, а затем второй очереди (для пустой очереди дважды вывести nil). Операции выделения и освобождения памяти не использовать.

Dynamic24. Даны две непустые очереди; адреса начала и конца первой равны P1 и P2, а второй — P3 и P4. Очереди содержат одинаковое количество элементов. Объединить очереди в одну, в которой элементы исходных очередей чередуются (начиная с первого элемента первой очереди). Вывести указатели на начало и конец полученной очереди. Операции выделения и освобождения памяти не использовать.

Dynamic25. Даны две непустые очереди; адреса начала и конца первой равны P1 и P2, а второй — P3 и P4. Элементы каждой из очередей упорядочены по возрастанию (в направлении от начала очереди к концу). Объединить очереди в одну с сохранением упорядоченности элементов. Вывести указатели на начало и конец полученной очереди. Операции выделения и освобождения памяти не использовать, поля Data не изменять.

Dynamic26. Даны указатели P1 и P2 на начало и конец очереди (если очередь является пустой, то P1 = P2 = nil). Также дано число N (> 0) и набор из N чисел. Описать тип TQueue — запись с двумя полями Head и Tail типа PNode (поля указывают на начало и конец очереди) — и процедуру Enqueue(Q, D), которая добавляет в конец очереди Q новый элемент со значением D (Q — входной и выходной параметр типа TQueue, D — входной параметр целого типа). С помощью процедуры Enqueue добавить в исходную очередь данный набор чисел и вывести новые адреса ее начала и конца.

Dynamic27. Даны указатели P1 и P2 на начало и конец очереди, содержащей не менее пяти элементов. Используя тип TQueue (см. задание Dynamic26), описать функцию Dequeue(Q) целого типа, которая извлекает из очереди первый (начальный) элемент, возвращает его значение и освобождает память, занимаемую извлеченным элементом (Q — входной и выходной параметр типа TQueue). С помощью функции Dequeue извлечь из исходной очереди пять начальных элементов и вывести их значения. Вывести также адреса начала и конца результирующей очереди (если очередь окажется пустой, то эти адреса должны быть равны nil).

Dynamic28. Даны указатели P1 и P2 на начало и конец очереди. Используя тип TQueue (см. задание Dynamic26), описать функцию QueueIsEmpty(Q) логического типа, которая возвращает True, если очередь Q пуста, и False в противном случае (Q — входной параметр типа TQueue). Используя эту функцию для проверки состояния очереди, а также функцию Dequeue из задания Dynamic27, извлечь из исходной очереди пять начальных элементов (или все содержащиеся в ней элементы, если их менее пяти) и вывести их значения. Вывести также значение функции QueueIsEmpty для полученной очереди и новые адреса ее начала и конца.

Динамические структуры данных: двусвязный список

В заданиях данной подгруппы структура «двусвязный список» (doubly linked list) моделируется цепочкой узлов-записей типа TNode, связанных как с предыдущим, так и с последующим узлом (см. первое задание данной подгруппы). Поле Next последнего элемента цепочки и поле Prev первого элемента цепочки равны nil. Для доступа к любому элементу двусвязного списка достаточно иметь указатель на один из его элементов, однако для ускорения операций со списком удобно хранить три указателя: на первый элемент списка (first), на его последний элемент (last) и на текущий элемент (current). Для пустого списка все эти указатели полагаются равными nil. Как в случае стека и очереди, значением элемента списка считается значение его поля Data.

Dynamic29. Дан адрес P2 записи типа TNode, содержащей поле Data (целого типа) и поля Prev и Next (типа PNode — указателя на TNode). Эта запись связана полями Prev и Next соответственно с предыдущей и последующей записью того же типа. Вывести значения полей Data предыдущей и последующей записи, а также адреса P1 и P3 предыдущей и последующей записи.

Dynamic30. Дан указатель P1 на начало непустой цепочки элементов-записей типа TNode, связанных между собой с помощью поля Next. Используя поле Prev записи TNode, преобразовать исходную (односвязную) цепочку в двусвязную, в которой каждый элемент связан не только с последующим элементом (с помощью поля Next), но и с предыдущим (с помощью поля Prev). Поле Prev первого элемента положить равным nil. Вывести указатель на последний элемент преобразованной цепочки.

Dynamic31. Дан указатель P0 на один из элементов непустого двусвязного списка. Вывести число N — количество элементов в списке, а также указатели P1 и P2 на первый и последний элементы списка.

Dynamic32. Даны числа D1 и D2 и указатель P0 на один из элементов непустого двусвязного списка. Добавить в начало списка новый элемент со значением D1, а в конец — новый элемент со значением D2. Вывести адреса первого и последнего элементов полученного списка.

Dynamic33. Дано число D и указатель P0 на один из элементов непустого двусвязного списка. Вставить перед данным элементом списка новый элемент со значением D и вывести указатель на добавленный элемент списка.

Dynamic34. Дано число D и указатель P0 на один из элементов непустого двусвязного списка. Вставить после данного элемента списка новый элемент со значением D и вывести указатель на добавленный элемент списка.

Dynamic35. Даны указатели P1 и P2 на первый и последний элементы двусвязного списка, содержащего не менее двух элементов. Продублировать в списке первый и последний элементы (новые элементы добавлять перед существующими элементами с такими же значениями) и вывести указатель на первый элемент преобразованного списка.

Dynamic36. Даны указатели P1 и P2 на первый и последний элементы двусвязного списка, содержащего не менее двух элементов. Продублировать в списке первый и последний элементы (новые элементы добавлять после существующих элементов с такими же значениями) и вывести указатель на последний элемент преобразованного списка.

Dynamic37. Дан указатель P1 на первый элемент непустого двусвязного списка. Продублировать в списке все элементы с нечетными номерами (новые элементы добавлять перед существующими элементами с такими же значениями) и вывести указатель на первый элемент преобразованного списка.

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

Dynamic39. Дан указатель P1 на первый элемент непустого двусвязного списка. Продублировать в списке все элементы с нечетными значениями (новые элементы добавлять перед существующими элементами с такими же значениями) и вывести указатель на первый элемент преобразованного списка.

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

Dynamic41. Дан указатель P0 на один из элементов непустого двусвязного списка. Удалить из списка данный элемент и вывести два указателя: на элемент, предшествующий удаленному, и на элемент, следующий за удаленным (один или оба этих элемента могут отсутствовать; для отсутствующих элементов выводить nil). После удаления элемента из списка освободить память, занимаемую этим элементом.

Dynamic42. Дан указатель P1 на первый элемент двусвязного списка, содержащего не менее двух элементов. Удалить из списка все элементы с нечетными номерами и вывести указатель на первый элемент преобразованного списка. После удаления элементов из списка освобождать память, которую они занимали.

Dynamic43. Дан указатель P1 на первый элемент непустого двусвязного списка. Удалить из списка все элементы с нечетными значениями и вывести указатель на первый элемент преобразованного списка (если в результате удаления элементов список окажется пустым, то вывести nil). После удаления элементов из списка освобождать память, которую они занимали.

Dynamic44. Дан указатель P0 на один из элементов непустого двусвязного списка. Переместить данный элемент в конец списка и вывести указатели на первый и последний элементы преобразованного списка. Операции выделения и освобождения памяти не использовать, поля Data не изменять.

Dynamic45. Дан указатель P0 на один из элементов непустого двусвязного списка. Переместить данный элемент в начало списка и вывести указатели на первый и последний элементы преобразованного списка. Операции выделения и освобождения памяти не использовать, поля Data не изменять.

Dynamic46. Дано число K (> 0) и указатель P0 на один из элементов непустого двусвязного списка. Переместить в списке данный элемент на K позиций вперед (если после данного элемента находится менее K элементов, то переместить его в конец списка). Вывести указатели на первый и последний элементы преобразованного списка. Операции выделения и освобождения памяти не использовать, поля Data не изменять.

Dynamic47. Дано число K (> 0) и указатель P0 на один из элементов непустого двусвязного списка. Переместить в списке данный элемент на K позиций назад (если перед данным элементом находится менее K элементов, то переместить его в начало списка). Вывести указатели на первый и последний элементы преобразованного списка. Операции выделения и освобождения памяти не использовать, поля Data не изменять.

Dynamic48. Даны указатели PX и PY на два различных элемента двусвязного списка (элемент с адресом PX находится в списке перед элементом с адресом PY, но не обязательно рядом с ним). Поменять местами данные элементы и вывести указатель на первый элемент преобразованного списка. Операции выделения и освобождения памяти не использовать, поля Data не изменять.

Dynamic49. Дан указатель P1 на первый элемент непустого двусвязного списка. Перегруппировать его элементы, переместив все элементы с нечетными номерами в конец списка (в том же порядке) и вывести указатель на первый элемент преобразованного списка. Операции выделения и освобождения памяти не использовать, поля Data не изменять.

Dynamic50. Дан указатель P1 на первый элемент непустого двусвязного списка. Перегруппировать его элементы, переместив все элементы с нечетными значениями в конец списка (в том же порядке) и вывести указатель на первый элемент преобразованного списка. Операции выделения и освобождения памяти не использовать, поля Data не изменять.

Dynamic51. Даны два непустых двусвязных списка и связанные с ними указатели: P1 и P2 указывают на первый и последний элементы первого списка, P0 — на один из элементов второго. Объединить исходные списки, поместив все элементы первого списка (в том же порядке) перед данным элементом второго списка, и вывести указатели на первый и последний элементы объединенного списка. Операции выделения и освобождения памяти не использовать.

Dynamic52. Даны два непустых двусвязных списка и связанные с ними указатели: P1 и P2 указывают на первый и последний элементы первого списка, P0 — на один из элементов второго. Объединить исходные списки, поместив все элементы первого списка (в том же порядке) после данного элемента второго списка, и вывести указатели на первый и последний элементы объединенного списка. Операции выделения и освобождения памяти не использовать.

Dynamic53. Даны указатели PX и PY на два различных элемента двусвязного списка; элемент с адресом PX находится в списке перед элементом с адресом PY, но не обязательно рядом с ним. Переместить элементы, расположенные между данными элементами (включая данные элементы), в новый список (в том же порядке). Вывести указатели на первые элементы преобразованного и нового списков. Если преобразованный список окажется пустым, то связанный с ним указатель положить равным nil. Операции выделения и освобождения памяти не использовать.

Dynamic54. Даны указатели PX и PY на два различных элемента двусвязного списка; элемент с адресом PX находится в списке перед элементом с адресом PY, но не обязательно рядом с ним. Переместить элементы, расположенные между данными элементами (не включая данные элементы), в новый список (в том же порядке). Вывести указатели на первые элементы преобразованного и нового списков. Если новый список окажется пустым, то связанный с ним указатель положить равным nil. Операции выделения и освобождения памяти не использовать.

Dynamic55. Дан указатель P1 на первый элемент непустого двусвязного списка. Преобразовать список в циклический, записав в поле Next последнего элемента списка адрес его первого элемента, а в поле Prev первого элемента — адрес последнего элемента. Вывести указатель на элемент, который был последним элементом исходного списка.

Dynamic56. Даны указатели P1 и P2 на первый и последний элементы непустого двусвязного списка, содержащего четное количество элементов. Преобразовать список в два циклических списка (см. задание Dynamic55), первый из которых содержит первую половину элементов исходного списка, а второй — вторую половину. Вывести указатели P3 и P4 на два средних элемента исходного списка (элемент с адресом P3 должен входить в первый циклический список, а элемент с адресом P4 — во второй). Операции выделения и освобождения памяти не использовать.

Dynamic57. Дано число K (> 0) и указатели P1 и P2 на первый и последний элементы непустого двусвязного списка. Осуществить циклический сдвиг элементов списка на K позиций вперед (т. е. в направлении от начала к концу списка) и вывести указатели на первый и последний элементы полученного списка. Для выполнения циклического сдвига преобразовать исходный список в циклический (см. задание Dynamic55), после чего «разорвать» его в позиции, соответствующей данному значению K. Операции выделения и освобождения памяти не использовать.

Dynamic58. Дано число K (> 0) и указатели P1 и P2 на первый и последний элементы непустого двусвязного списка. Осуществить циклический сдвиг элементов списка на K позиций назад (т. е. в направлении от конца к началу списка) и вывести указатели на первый и последний элементы полученного списка. Для выполнения циклического сдвига преобразовать исходный список в циклический (см. задание Dynamic55), после чего «разорвать» его в позиции, соответствующей данному значению K. Операции выделения и освобождения памяти не использовать.

Dynamic59. Даны указатели P1, P2 и P3 на первый, последний и текущий элементы двусвязного списка (если список является пустым, то P1 = P2 = P3 = nil). Также дано число N (> 0) и набор из N чисел. Описать тип TList — запись с полями First, Last и Current типа PNode (поля указывают соответственно на первый, последний и текущий элементы списка) — и процедуру InsertLast(L, D), которая добавляет новый элемент со значением D в конец списка L (L — входной и выходной параметр типа TList, D — входной параметр целого типа). Добавленный элемент становится текущим. С помощью этой процедуры добавить в конец исходного списка данный набор чисел (в том же порядке) и вывести новые адреса его первого, последнего и текущего элементов.

Dynamic60. Даны указатели P1, P2 и P3 на первый, последний и текущий элементы двусвязного списка (если список является пустым, то P1 = P2 = P3 = nil). Также дано число N (> 0) и набор из N чисел. Используя тип TList (см. задание Dynamic59), описать процедуру InsertFirst(L, D), которая добавляет новый элемент со значением D в начало списка L (L — входной и выходной параметр типа TList, D — входной параметр целого типа). Добавленный элемент становится текущим. С помощью этой процедуры добавить в начало исходного списка данный набор чисел (добавленные числа будут располагаться в списке в обратном порядке) и вывести новые адреса его первого, последнего и текущего элементов.

Dynamic61. Дан непустой двусвязный список, первый, последний и текущий элементы которого имеют адреса P1, P2 и P3. Также даны пять чисел. Используя тип TList (см. задание Dynamic59), описать процедуру InsertBefore(L, D), которая вставляет новый элемент со значением D перед текущим элементом списка L (L — входной и выходной параметр типа TList, D — входной параметр целого типа). Вставленный элемент становится текущим. С помощью этой процедуры вставить пять данных чисел в исходный список и вывести новые адреса его первого, последнего и текущего элементов.

Dynamic62. Дан непустой двусвязный список, первый, последний и текущий элементы которого имеют адреса P1, P2 и P3. Также даны пять чисел. Используя тип TList (см. задание Dynamic59), описать процедуру InsertAfter(L, D), которая вставляет новый элемент со значением D после текущего элемента списка L (L — входной и выходной параметр типа TList, D — входной параметр целого типа). Вставленный элемент становится текущим. С помощью этой процедуры вставить пять данных чисел в исходный список и вывести новые адреса его первого, последнего и текущего элементов.

Dynamic63. Дан непустой двусвязный список, первый, последний и текущий элементы которого имеют адреса P1, P2 и P3. Используя тип TList (см. задание Dynamic59), описать процедуры ToFirst(L) (делает текущим первый элемент списка L), ToNext(L) (делает текущим в списке L следующий элемент, если он существует), SetData(L, D) (присваивает текущему элементу списка L значение D целого типа) и функцию IsLast(L) логического типа (возвращает True, если текущий элемент списка L является его последним элементом, и False в противном случае). Параметр L имеет тип TList; в процедурах ToFirst и ToNext он является входным и выходным. С помощью этих процедур и функций присвоить нулевые значения элементам исходного списка с нечетными номерами и вывести количество элементов в списке, а также новые адреса его первого, последнего и текущего элементов (текущим элементом должен стать последний элемент списка).

Dynamic64. Дан непустой двусвязный список, первый, последний и текущий элементы которого имеют адреса P1, P2 и P3. Используя тип TList (см. задание Dynamic59), описать процедуры ToLast(L) (делает текущим последний элемент списка L), ToPrev(L) (делает текущим в списке L предыдущий элемент, если он существует) и функции GetData(L) целого типа (возвращает значение текущего элемента списка L), IsFirst(L) логического типа (возвращает True, если текущий элемент списка L является его первым элементом, и False в противном случае). Параметр L имеет тип TList; в процедурах ToLast и ToPrev он является входным и выходным. С помощью этих процедур и функций вывести все четные значения элементов исходного списка, просматривая список с конца. Вывести также количество элементов в списке.

Dynamic65. Даны указатели P1, P2 и P3 на первый, последний и текущий элементы двусвязного списка, содержащего не менее пяти элементов. Используя тип TList (см. задание Dynamic59), описать функцию DeleteCurrent(L) целого типа, удаляющую из списка L текущий элемент и возвращающую его значение (L — входной и выходной параметр типа TList). После удаления элемента текущим становится следующий элемент или, если следующего элемента не существует, последний элемент списка. Функция также освобождает память, занимаемую удаленным элементом. С помощью этой функции удалить из исходного списка пять элементов и вывести их значения. Вывести также новые адреса первого, последнего и текущего элементов списка (для пустого списка вывести три константы nil).

Dynamic66. Даны указатели P1, P2 и P3 на первый, последний и текущий элементы непустого двусвязного списка. Используя тип TList (см. задание Dynamic59), описать процедуру SplitList(L1, L2), которая переносит элементы списка L1 от текущего до последнего в новый список L2 (таким образом, список L1 делится на две части, причем первая часть может оказаться пустой). Параметры процедуры имеют тип TList; первый параметр является входным и выходным, второй — выходным. Текущими элементами непустых результирующих списков становятся их первые элементы. Операции выделения и освобождения памяти в процедуре не использовать. С помощью этой процедуры разбить исходный список на два и вывести адреса первого, последнего и текущего элементов полученных списков.

Dynamic67. Даны указатели на первый, последний и текущий элементы двух непустых двусвязных списков. Используя тип TList (см. задание Dynamic59), описать процедуру AddList(L1, L2), которая добавляет все элементы из списка L1 (в том же порядке) в конец списка L2; в результате список L1 становится пустым. Текущим элементом списка L2 становится первый из добавленных элементов. Оба параметра процедуры имеют тип TList и являются входными и выходными. Операции выделения и освобождения памяти в процедуре не использовать. С помощью этой процедуры добавить первый из исходных списков в конец второго и вывести адреса первого, последнего и текущего элементов объединенного списка.

Dynamic68. Даны указатели на первый, последний и текущий элементы двух непустых двусвязных списков. Используя тип TList (см. задание Dynamic59), описать процедуру InsertList(L1, L2), которая вставляет все элементы из списка L1 (в том же порядке) в список L2 перед его текущим элементом; в результате список L1 становится пустым. Текущим элементом списка L2 становится первый из вставленных элементов. Оба параметра процедуры имеют тип TList и являются входными и выходными. Операции выделения и освобождения памяти в процедуре не использовать. С помощью этой процедуры вставить первый из исходных списков в текущую позицию второго и вывести адреса первого, последнего и текущего элементов объединенного списка.

Dynamic69. Даны указатели на первый, последний и текущий элементы двух двусвязных списков (второй список может быть пустым). Используя тип TList (см. задание Dynamic59), описать процедуру MoveCurrent(L1, L2), которая перемещает текущий элемент списка L1 в список L2 (элемент вставляется после текущего элемента списка L2 и сам становится текущим; в списке L1 текущим становится следующий элемент или, если следующего элемента не существует, последний элемент). Оба параметра процедуры имеют тип TList и являются входными и выходными. Операции выделения и освобождения памяти в процедуре не использовать. С помощью этой процедуры переместить текущий элемент первого списка во второй и вывести адреса первого, последнего и текущего элементов полученных списков.

Динамические структуры данных: список с барьерным элементом

Реализация двусвязного списка в виде цепочки узлов, ограниченной по краям нулевыми указателями, не является единственно возможной. Двусвязный список можно также реализовать в виде замкнутой цепочки узлов с дополнительным фиктивным, или барьерным, элементом. Этот барьерный элемент связан своими полями Next и Prev с первым и последним «настоящим» элементом списка соответственно, поэтому, имея указатель на барьерный элемент, можно сразу перейти как к первому, так и к последнему элементу списка (естественно, первый и последний элементы также связаны с барьерным элементом своими полями Prev и Next соответственно). Для работы с двусвязным списком, снабженным барьерным элементом, достаточно хранить два указателя: Barrier, указывающий на барьерный элемент, и Current, указывающий на текущий элемент (который может быть как «настоящим», так и барьерным элементом). Поле Data барьерного элемента может быть произвольным; для определенности его можно положить равным 0. Пустой список в данной реализации представляет собой единственный барьерный элемент, «замкнутый на себя».

Задания данной подгруппы посвящены двусвязным спискам с барьерным элементом.

Dynamic70. Даны указатели P1 и P2 на первый и последний элементы двусвязного списка, реализованного в виде цепочки узлов, ограниченной по краям нулевыми указателями (если список пуст, то P1 = P2 = nil). Преобразовать исходный список в циклический список (см. задание Dynamic55), снабженный барьерным элементом. Барьерный элемент должен иметь значение 0 и быть связан своими полями Next и Prev с первым и последним элементом исходного списка (в случае пустого исходного списка поля Next и Prev барьерного элемента должны указывать на сам барьерный элемент). Вывести указатель на барьерный элемент полученного списка. Операцию выделения памяти использовать только для создания барьерного элемента.

Dynamic71. Даны указатели P1 и P2 на барьерный и текущий элементы двусвязного списка (о списке с барьерным элементом см. задание Dynamic70). Разбить список на два, перенеся во второй список все элементы от текущего до последнего и добавив ко второму списку барьерный элемент. Если текущий элемент исходного списка является барьерным элементом, то второй список должен быть пустым (т. е. состоять только из барьерного элемента). Вывести указатель на барьерный элемент второго списка. Операцию выделения памяти использовать только для создания барьерного элемента второго списка.

Dynamic72. Даны указатели P1 и P2 на барьерные элементы двух двусвязных списков (о списке с барьерным элементом см. задание Dynamic70). Объединить исходные списки, связав конец первого и начало второго списка (барьерным элементом объединенного списка должен остаться барьерный элемент первого списка). Вывести указатели на первый и последний элементы объединенного списка (если объединенный список является пустым, то дважды вывести указатель на его барьерный элемент). После удаления лишнего барьерного элемента освободить занимаемую им память.

Dynamic73. Даны указатели P1 и P2 на барьерные элементы двух двусвязных списков (о списке с барьерным элементом см. задание Dynamic70). Объединить исходные списки, связав конец первого и начало второго списка (барьерным элементом объединенного списка должен остаться барьерный элемент второго списка). Вывести указатели на первый и последний элементы объединенного списка (если объединенный список является пустым, то дважды вывести указатель на его барьерный элемент). После удаления лишнего барьерного элемента освободить занимаемую им память.

Dynamic74. Даны указатели P1 и P2 на барьерный и текущий элементы двусвязного списка (о списке с барьерным элементом см. задание Dynamic70). Также дано число N (> 0) и набор из N чисел. Описать тип TListB — запись с полями Barrier и Current типа PNode (поля указывают соответственно на барьерный и текущий элементы списка) — и процедуру LBInsertLast(L, D), которая добавляет новый элемент со значением D в конец списка L (L — входной и выходной параметр типа TListB, D — входной параметр целого типа). Добавленный элемент становится текущим. С помощью этой процедуры добавить в конец исходного списка данный набор чисел (в том же порядке) и вывести адрес текущего элемента полученного списка.

Dynamic75. Даны указатели P1 и P2 на барьерный и текущий элементы двусвязного списка. Также дано число N (> 0) и набор из N чисел. Используя тип TListB (см. задание Dynamic74), описать процедуру LBInsertFirst(L, D), которая добавляет новый элемент со значением D в начало списка L (L — входной и выходной параметр типа TListB, D — входной параметр целого типа). Добавленный элемент становится текущим. С помощью этой процедуры добавить в начало исходного списка данный набор чисел (добавленные числа будут располагаться в списке в обратном порядке) и вывести адрес текущего элемента полученного списка.

Dynamic76. Даны указатели P1 и P2 на барьерный и текущий элементы двусвязного списка. Также даны пять чисел. Используя тип TListB (см. задание Dynamic74), описать процедуру LBInsertBefore(L, D), которая вставляет новый элемент со значением D перед текущим элементом списка L (L — входной и выходной параметр типа TListB, D — входной параметр целого типа). Вставленный элемент становится текущим. С помощью этой процедуры вставить пять данных чисел в исходный список и вывести новый адрес его текущего элемента.

Dynamic77. Даны указатели P1 и P2 на барьерный и текущий элементы двусвязного списка. Также даны пять чисел. Используя тип TListB (см. задание Dynamic74), описать процедуру LBInsertAfter(L, D), которая вставляет новый элемент со значением D после текущего элемента списка L (L — входной и выходной параметр типа TListB, D — входной параметр целого типа). Вставленный элемент становится текущим. С помощью этой процедуры вставить пять данных чисел в исходный список и вывести новый адрес его текущего элемента.

Dynamic78. Даны указатели P1 и P2 на барьерный и текущий элементы двусвязного списка. Используя тип TListB (см. задание Dynamic74), описать процедуры LBToFirst(L) (делает текущим первый элемент списка L), LBToNext(L) (делает текущим в списке L следующий элемент), LBSetData(L, D) (присваивает текущему элементу списка L значение D целого типа, если данный элемент не является барьерным) и функцию IsBarrier(L) логического типа (возвращает True, если текущий элемент списка L является его барьерным элементом, и False в противном случае). Параметр L имеет тип TListB; в процедурах LBToFirst и LBToNext он является входным и выходным. С помощью этих процедур и функций присвоить нулевые значения элементам исходного списка с нечетными номерами и вывести количество элементов в списке, а также новый адрес текущего элемента списка (текущим элементом списка должен стать его барьерный элемент). Нумерация ведется от первого элемента списка; барьерный элемент не нумеруется и не учитывается при подсчете элементов.

Dynamic79. Даны указатели P1 и P2 на барьерный и текущий элементы двусвязного списка. Используя тип TListB (см. задание Dynamic74), описать процедуры LBToLast(L) (делает текущим последний элемент списка L), LBToPrev(L) (делает текущим в списке L предыдущий элемент) и функцию LBGetData(L) целого типа (возвращает значение текущего элемента списка L). Параметр L имеет тип TListB; в процедурах LBToLast и LBToPrev он является входным и выходным. С помощью этих процедур и функций, а также функции IsBarrier из задания Dynamic78, вывести все четные значения элементов исходного списка, просматривая список с конца. Вывести также количество элементов в списке. Барьерный элемент не обрабатывается и не учитывается при подсчете элементов.

Dynamic80. Даны указатели P1 и P2 на барьерный и текущий элементы непустого двусвязного списка, причем текущий элемент не совпадает с барьерным. Используя тип TListB (см. задание Dynamic74), описать функцию LBDeleteCurrent(L) целого типа, удаляющую из списка L текущий элемент и возвращающую его значение (L — входной и выходной параметр типа TListB). Текущим становится следующий элемент или, если следующий элемент является барьерным, предыдущий элемент списка. Функция также освобождает память, занимаемую удаленным элементом. Если текущим элементом является барьерный элемент, то функция не выполняет никаких действий и возвращает 0. С помощью этой функции, а также функции IsBarrier из задания Dynamic78, удалить из исходного списка пять элементов (или все элементы, если их менее пяти) и вывести их значения. Вывести также новый адрес текущего элемента списка.


Группы заданий

Динамические структуры данных: группа Dynamic (.NET)

[Перейти к указаниям] [Перейти к началу раздела «Группы заданий»] [Перейти к началу раздела «Указания»]

В варианте задачника для системы PascalABC.NET группа имеет имя ObjDyn. В веб-среде ProgrammingABC.NET WDE данная группа доступна для языков PascalABC.NET, C#, Visual Basic .NET под исходным именем Dynamic.

Все числа, используемые в заданиях на динамические структуры данных, являются целыми. Все объекты имеют тип Node, который определен в задачнике Programming Taskbook. В заданиях данной группы у объектов типа Node используются свойства Data, Next и Prev, поэтому при выполнении заданий можно считать, что класс Node включает следующие открытые свойства и методы:

[C#]

// Конструкторы:
public Node();
public Node(int aData);
public Node(int aData, Node aNext);
public Node(int aData, Node aNext, Node aPrev);
// Свойства (доступны для чтения и для записи):
public int Data;
public Node Next;
public Node Prev;
// Метод, освобождающий неуправляемые ресурсы, используемые объектом Node:
public void Dispose();

[VB.NET]

' Конструкторы:
Public Sub New()
Public Sub New(aData As Integer)
Public Sub New(aData As Integer, aNext As Node)
Public Sub New(aData As Integer, aNext As Node, _
aPrev As Node)
' Свойства (доступны для чтения и для записи):
Public Property Data() As Integer
Public Property Next() As Node
Public Property Prev() As Node
' Метод, освобождающий неуправляемые ресурсы, используемые объектом Node:
Public Sub Dispose() Implements IDisposable.Dispose

[PascalABC.NET]

// Конструкторы:
constructor Create;
constructor Create(aData: integer);
constructor Create(aData: integer; aNext: Node);
constructor Create(aData: integer; aNext, aPrev: Node);
// Свойства (доступны для чтения и для записи):
property Data: integer;
property Next: Node;
property Prev: Node;
// Метод, освобождающий неуправляемые ресурсы, используемые объектом:
procedure Dispose;

Во вводных заданиях, а также в заданиях на стек и очередь при работе с объектами типа Node свойство Prev не используется; в заданиях на списки используются все свойства объектов типа Node.

Так как в языках платформы .NET принята ссылочная объектная модель, т. е. любая переменная объектного типа является ссылкой на ту область памяти, в которой фактически размещен данный объект, выражение «вывести ссылку на объект» в формулировках заданий всегда означает, что требуется вывести значение переменной типа Node, связанной с этим объектом.

В заданиях, в которых идет речь о номерах элементов списка, предполагается, что элементы списка нумеруются от 1.

Динамические структуры данных: узлы и цепочки узлов

Dynamic1. Дан объект A1 типа Node, имеющий открытые свойства Data целого типа и Next типа Node. Свойство Next данного объекта содержит ссылку на объект A2 (того же типа Node). Вывести значения свойств Data обоих объектов, а также ссылку на объект A2.

Dynamic2. Дан объект A1 типа Node. Этот объект связан своим свойством Next со следующим объектом типа Node, он, в свою очередь, — со следующим, и так далее до объекта со свойством Next, равным null (таким образом, возникает цепочка связанных объектов). Вывести значения свойств Data для всех элементов цепочки, длину цепочки (т. е. число ее элементов) и ссылку на ее последний элемент.

Динамические структуры данных: стек

В заданиях данной подгруппы структура «стек» (stack) моделируется цепочкой связанных узлов-объектов типа Node. Свойство Next последнего элемента цепочки равно null. Вершиной стека (top) считается первый элемент цепочки. Для доступа к стеку используется переменная типа Node — ссылка на вершину стека (для пустого стека данная переменная полагается равной null). Значением элемента стека считается значение его свойства Data.

Dynamic3. Дано число D и вершина A1 непустого стека. Добавить элемент со значением D в стек и вывести ссылку A2 на новую вершину стека.

Dynamic4. Дано число N (> 0) и набор из N чисел. Создать стек, содержащий исходные числа (последнее число будет вершиной стека), и вывести ссылку на его вершину.

Dynamic5. Дана вершина A1 непустого стека. Извлечь из стека первый (верхний) элемент и вывести его значение D, а также ссылку A2 на новую вершину стека. Если после извлечения элемента стек окажется пустым, то положить A2 = null. После извлечения элемента из стека освободить ресурсы, используемые этим элементом, вызвав его метод Dispose.

Dynamic6. Дана вершина A1 стека, содержащего не менее десяти элементов. Извлечь из стека первые девять элементов и вывести их значения. Вывести также ссылку на новую вершину стека. После извлечения элементов из стека освобождать ресурсы, которые они использовали, вызывая для этих элементов метод Dispose.

Dynamic7. Дана вершина A1 стека (если стек пуст, то A1 = null). Извлечь из стека все элементы и вывести их значения. Вывести также количество извлеченных элементов N (для пустого стека вывести 0). После извлечения элементов из стека освобождать ресурсы, которые они использовали, вызывая для этих элементов метод Dispose.

Dynamic8. Даны вершины A1 и A2 двух непустых стеков. Переместить все элементы из первого стека во второй (в результате элементы первого стека будут располагаться во втором стеке в порядке, обратном исходному) и вывести ссылку на новую вершину второго стека. Новые объекты типа Node не создавать.

Dynamic9. Даны вершины A1 и A2 двух непустых стеков. Перемещать элементы из первого стека во второй, пока значение вершины первого стека не станет четным (перемещенные элементы первого стека будут располагаться во втором стеке в порядке, обратном исходному). Если в первом стеке нет элементов с четными значениями, то переместить из первого стека во второй все элементы. Вывести ссылки на новые вершины первого и второго стека (если первый стек окажется пустым, то вывести для него константу null). Новые объекты типа Node не создавать.

Dynamic10. Дана вершина A1 непустого стека. Создать два новых стека, переместив в первый из них все элементы исходного стека с четными значениями, а во второй — с нечетными (элементы в новых стеках будут располагаться в порядке, обратном исходному; один из этих стеков может оказаться пустым). Вывести ссылки на вершины полученных стеков (для пустого стека вывести константу null). Новые объекты типа Node не создавать.

Dynamic11. Дана вершина A1 стека (если стек пуст, то A1 = null). Также дано число N (> 0) и набор из N чисел. Описать класс IntStack, содержащий следующие члены:

• закрытое поле top типа Node (вершина стека);
• конструктор с параметром aTop — вершиной существующего стека;
• процедура Push(D), которая добавляет в стек новый элемент со значением D (D — входной параметр целого типа);
• процедура Put (без параметров), которая выводит ссылку на поле top, используя метод Put класса PT.

С помощью метода Push добавить в исходный стек данный набор чисел (последнее число будет вершиной стека) и вывести ссылку на новую вершину стека, используя для этого метод Put класса IntStack.

Dynamic12. Дана вершина A1 стека, содержащего не менее пяти элементов. Включить в класс IntStack (см. задание Dynamic11) функцию Pop целого типа (без параметров), которая извлекает из стека первый (верхний) элемент, возвращает его значение и вызывает для него метод Dispose. С помощью метода Pop извлечь из исходного стека пять элементов и вывести их значения. Вывести также ссылку на новую вершину стека (если результирующий стек окажется пустым, то эта ссылка должна быть равна null).

Dynamic13. Дана вершина A1 стека. Включить в класс IntStack (см. задание Dynamic11) две функции: IsEmpty логического типа (возвращает true, если стек пуст, и false в противном случае) и Peek целого типа (возвращает значение вершины непустого стека, не удаляя ее из стека). Функции не имеют параметров. С помощью этих функций, а также функции Pop из задания Dynamic12, извлечь из исходного стека пять элементов (или все содержащиеся в нем элементы, если их менее пяти) и вывести их значения. Вывести также значение функции IsEmpty для результирующего стека и, если результирующий стек не является пустым, значение его новой вершины и ссылку на нее.

Динамические структуры данных: очередь

В заданиях данной подгруппы структура «очередь» (queue) моделируется цепочкой связанных узлов-объектов типа Node. Свойство Next последнего элемента цепочки равно null. Началом очереди («головой», head) считается первый элемент цепочки, концом («хвостом», tail) — ее последний элемент. Для возможности быстрого добавления в конец очереди нового элемента удобно хранить, помимо ссылки на начало очереди, также и ссылку на ее конец. В случае пустой очереди ссылки на ее начало и конец полагаются равными null. Как и для стека, значением элемента очереди считается значение его свойства Data.

Dynamic14. Дан набор из 10 чисел. Создать очередь, содержащую данные числа в указанном порядке (первое число будет размещаться в начале очереди, последнее — в конце), и вывести ссылки A1 и A2 на начало и конец очереди.

Dynamic15. Дан набор из 10 чисел. Создать две очереди: первая должна содержать числа из исходного набора с нечетными номерами (1, 3, …, 9), а вторая — с четными (2, 4, …, 10); порядок чисел в каждой очереди должен совпадать с порядком чисел в исходном наборе. Вывести ссылки на начало и конец первой, а затем второй очереди.

Dynamic16. Дан набор из 10 чисел. Создать две очереди: первая должна содержать все нечетные, а вторая — все четные числа из исходного набора (порядок чисел в каждой очереди должен совпадать с порядком чисел в исходном наборе). Вывести ссылки на начало и конец первой, а затем второй очереди (одна из очередей может оказаться пустой; в этом случае вывести для нее две константы null).

Dynamic17. Дано число D и ссылки A1 и A2 на начало и конец очереди (если очередь является пустой, то A1 = A2 = null). Добавить элемент со значением D в конец очереди и вывести ссылки на начало и конец полученной очереди.

Dynamic18. Дано число D и ссылки A1 и A2 на начало и конец очереди, содержащей не менее двух элементов. Добавить элемент со значением D в конец очереди и извлечь из очереди первый (начальный) элемент. Вывести значение извлеченного элемента, а также ссылки на начало и конец полученной очереди. После извлечения элемента из очереди вызвать для него метод Dispose.

Dynamic19. Дано число N (> 0) и ссылки A1 и A2 на начало и конец непустой очереди. Извлечь из очереди N начальных элементов и вывести их значения (если очередь содержит менее N элементов, то извлечь все ее элементы). Вывести также ссылки на начало и конец полученной очереди (для пустой очереди дважды вывести null). После извлечения элементов вызывать для них метод Dispose.

Dynamic20. Даны ссылки A1 и A2 на начало и конец непустой очереди. Извлекать из очереди элементы, пока значение начального элемента очереди не станет четным, и выводить значения извлеченных элементов (если очередь не содержит элементов с четными значениями, то извлечь все ее элементы). Вывести также ссылки на начало и конец полученной очереди (для пустой очереди дважды вывести null). После извлечения элементов вызывать для них метод Dispose.

Dynamic21. Даны две очереди; начало и конец первой равны A1 и A2, а второй — A3 и A4 (если очередь является пустой, то соответствующие объекты равны null). Переместить все элементы первой очереди (в порядке от начала к концу) в конец второй очереди и вывести ссылки на начало и конец преобразованной второй очереди. Новые объекты типа Node не создавать.

Dynamic22. Дано число N (> 0) и две непустые очереди; начало и конец первой равны A1 и A2, а второй — A3 и A4. Переместить N начальных элементов первой очереди в конец второй очереди. Если первая очередь содержит менее N элементов, то переместить из первой очереди во вторую все элементы. Вывести новые ссылки на начало и конец первой, а затем второй очереди (для пустой очереди дважды вывести null). Новые объекты типа Node не создавать.

Dynamic23. Даны две непустые очереди; начало и конец первой равны A1 и A2, а второй — A3 и A4. Перемещать элементы из начала первой очереди в конец второй, пока значение начального элемента первой очереди не станет четным (если первая очередь не содержит четных элементов, то переместить из первой очереди во вторую все элементы). Вывести новые ссылки на начало и конец первой, а затем второй очереди (для пустой очереди дважды вывести null). Новые объекты типа Node не создавать.

Dynamic24. Даны две непустые очереди; начало и конец первой равны A1 и A2, а второй — A3 и A4. Очереди содержат одинаковое количество элементов. Объединить очереди в одну, в которой элементы исходных очередей чередуются (начиная с первого элемента первой очереди). Вывести ссылки на начало и конец полученной очереди. Новые объекты типа Node не создавать.

Dynamic25. Даны две непустые очереди; начало и конец первой равны A1 и A2, а второй — A3 и A4. Элементы каждой из очередей упорядочены по возрастанию (в направлении от начала очереди к концу). Объединить очереди в одну с сохранением упорядоченности элементов. Вывести ссылки на начало и конец полученной очереди. Новые объекты типа Node не создавать, свойства Data не изменять.

Dynamic26. Даны ссылки A1 и A2 на начало и конец очереди (если очередь является пустой, то A1 = A2 = null). Также дано число N (> 0) и набор из N чисел. Описать класс IntQueue, содержащий следующие члены:

• закрытые поля head и tail типа Node (начало и конец очереди);
• конструктор с параметрами aHead, aTail — началом и концом существующей очереди;
• процедура Enqueue(D), которая добавляет в конец очереди новый элемент со значением D (D — входной параметр целого типа);
• процедура Put (без параметров), которая выводит ссылки на поля head и tail, используя метод Put класса PT.

С помощью метода Enqueue добавить в исходную очередь данный набор чисел и вывести новые ссылки на ее начало и конец, используя для этого метод Put класса IntQueue.

Dynamic27. Даны ссылки A1 и A2 на начало и конец очереди, содержащей не менее пяти элементов. Включить в класс IntQueue (см. задание Dynamic26) функцию Dequeue целого типа (без параметров), которая извлекает из очереди первый (начальный) элемент, возвращает его значение и вызывает для него метод Dispose. С помощью функции Dequeue извлечь из исходной очереди пять начальных элементов и вывести их значения. Вывести также ссылки на начало и конец результирующей очереди (если очередь окажется пустой, то эти ссылки должны быть равны null).

Dynamic28. Даны ссылки A1 и A2 на начало и конец очереди. Включить в класс IntQueue (см. задание Dynamic26) функцию IsEmpty логического типа (без параметров), которая возвращает true, если очередь пуста, и false в противном случае. Используя эту функцию для проверки состояния очереди, а также функцию Dequeue из задания Dynamic27, извлечь из исходной очереди пять начальных элементов (или все содержащиеся в ней элементы, если их менее пяти) и вывести их значения. Вывести также значение функции IsEmpty для полученной очереди и новые ссылки на ее начало и конец.

Динамические структуры данных: двусвязный список

В заданиях данной подгруппы структура «двусвязный список» (doubly linked list) моделируется цепочкой узлов-объектов типа Node, связанных как с предыдущим, так и с последующим узлом. Свойство Next последнего элемента цепочки и свойство Prev первого элемента цепочки равны null. Для доступа к любому элементу двусвязного списка достаточно иметь ссылку на один из его элементов, однако для ускорения операций со списком удобно хранить три ссылки: на первый элемент списка (first), на его последний элемент (last) и на текущий элемент (current). Для пустого списка все эти ссылки полагаются равными null. Как в случае стека и очереди, значением элемента списка считается значение его свойства Data.

Dynamic29. Дан объект A2 типа Node, имеющий открытое свойство Data целого типа, а также открытые свойства Prev и Next типа Node. Свойство Prev объекта A2 содержит ссылку на предыдущий объект того же типа, а свойство Next — ссылку на следующий объект. Вывести значения свойств Data предыдущего и следующего объекта, а также ссылки A1 и A3 на предыдущий и следующий объект.

Dynamic30. Дана ссылка A1 на начало непустой цепочки элементов-объектов типа Node, связанных между собой с помощью своих свойств Next. Используя свойства Prev данных объектов, преобразовать исходную (односвязную) цепочку в двусвязную, в которой каждый элемент связан не только с последующим элементом (с помощью свойства Next), но и с предыдущим (с помощью свойства Prev). Свойство Prev первого элемента положить равным null. Вывести ссылку A2 на последний элемент преобразованной цепочки.

Dynamic31. Дана ссылка A0 на один из элементов непустого двусвязного списка. Вывести число N — количество элементов в списке, а также ссылки A1 и A2 на первый и последний элементы списка.

Dynamic32. Даны числа D1 и D2 и ссылка A0 на один из элементов непустого двусвязного списка. Добавить в начало списка новый элемент со значением D1, а в конец — новый элемент со значением D2. Вывести ссылки на первый и последний элементы полученного списка.

Dynamic33. Дано число D и ссылка A0 на один из элементов непустого двусвязного списка. Вставить перед данным элементом списка новый элемент со значением D и вывести ссылку на добавленный элемент списка.

Dynamic34. Дано число D и ссылка A0 на один из элементов непустого двусвязного списка. Вставить после данного элемента списка новый элемент со значением D и вывести ссылку на добавленный элемент списка.

Dynamic35. Даны ссылки A1 и A2 на первый и последний элементы двусвязного списка, содержащего не менее двух элементов. Продублировать в списке первый и последний элементы (новые элементы добавлять перед существующими элементами с такими же значениями) и вывести ссылку на первый элемент преобразованного списка.

Dynamic36. Даны ссылки A1 и A2 на первый и последний элементы двусвязного списка, содержащего не менее двух элементов. Продублировать в списке первый и последний элементы (новые элементы добавлять после существующих элементов с такими же значениями) и вывести ссылку на последний элемент преобразованного списка.

Dynamic37. Дан первый элемент A1 непустого двусвязного списка. Продублировать в списке все элементы с нечетными номерами (новые элементы добавлять перед существующими элементами с такими же значениями) и вывести ссылку на первый элемент преобразованного списка.

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

Dynamic39. Дан первый элемент A1 непустого двусвязного списка. Продублировать в списке все элементы с нечетными значениями (новые элементы добавлять перед существующими элементами с такими же значениями) и вывести ссылку на первый элемент преобразованного списка.

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

Dynamic41. Дана ссылка A0 на один из элементов непустого двусвязного списка. Удалить из списка данный элемент и вывести две ссылки: на элемент, предшествующий удаленному, и на элемент, следующий за удаленным (один или оба этих элемента могут отсутствовать; для отсутствующих элементов выводить null). После удаления элемента из списка вызвать для него метод Dispose.

Dynamic42. Дан первый элемент A1 двусвязного списка, содержащего не менее двух элементов. Удалить из списка все элементы с нечетными номерами и вывести ссылку на первый элемент преобразованного списка. После удаления элементов из списка вызывать для них метод Dispose.

Dynamic43. Дан первый элемент A1 непустого двусвязного списка. Удалить из списка все элементы с нечетными значениями и вывести ссылку на первый элемент преобразованного списка (если в результате удаления элементов список окажется пустым, то вывести null). После удаления элементов из списка вызывать для них метод Dispose.

Dynamic44. Дана ссылка A0 на один из элементов непустого двусвязного списка. Переместить данный элемент в конец списка и вывести ссылки на первый и последний элементы преобразованного списка. Новые объекты типа Node не создавать, свойства Data не изменять.

Dynamic45. Дана ссылка A0 на один из элементов непустого двусвязного списка. Переместить данный элемент в начало списка и вывести ссылки на первый и последний элементы преобразованного списка. Новые объекты типа Node не создавать, свойства Data не изменять.

Dynamic46. Дано число K (> 0) и ссылка A0 на один из элементов непустого двусвязного списка. Переместить в списке данный элемент на K позиций вперед (если после данного элемента находится менее K элементов, то переместить его в конец списка). Вывести ссылки на первый и последний элементы преобразованного списка. Новые объекты типа Node не создавать, свойства Data не изменять.

Dynamic47. Дано число K (> 0) и ссылка A0 на один из элементов непустого двусвязного списка. Переместить в списке данный элемент на K позиций назад (если перед данным элементом находится менее K элементов, то переместить его в начало списка). Вывести ссылки на первый и последний элементы преобразованного списка. Новые объекты типа Node не создавать, свойства Data не изменять.

Dynamic48. Даны ссылки AX и AY на два различных элемента двусвязного списка (элемент AX находится в списке перед элементом AY, но не обязательно рядом с ним). Поменять местами данные элементы и вывести ссылку на первый элемент преобразованного списка. Новые объекты типа Node не создавать, свойства Data не изменять.

Dynamic49. Дан первый элемент A1 непустого двусвязного списка. Перегруппировать элементы списка, переместив все элементы с нечетными номерами в конец списка (в том же порядке) и вывести ссылку на первый элемент преобразованного списка. Новые объекты типа Node не создавать, свойства Data не изменять.

Dynamic50. Дан первый элемент A1 непустого двусвязного списка. Перегруппировать элементы списка, переместив все элементы с нечетными значениями в конец списка (в том же порядке) и вывести ссылку на первый элемент преобразованного списка. Новые объекты типа Node не создавать, свойства Data не изменять.

Dynamic51. Для двух непустых двусвязных списков даны следующие объекты: A1 и A2 — начало и конец первого списка, A0 — один из элементов второго списка. Объединить исходные списки, поместив все элементы первого списка (в том же порядке) перед данным элементом второго списка, и вывести ссылки на первый и последний элементы объединенного списка. Новые объекты типа Node не создавать.

Dynamic52. Для двух непустых двусвязных списков даны следующие объекты: A1 и A2 — начало и конец первого списка, A0 — один из элементов второго списка. Объединить исходные списки, поместив все элементы первого списка (в том же порядке) после данного элемента второго списка, и вывести ссылки на первый и последний элементы объединенного списка. Новые объекты типа Node не создавать.

Dynamic53. Даны ссылки AX и AY на два различных элемента двусвязного списка; элемент AX находится в списке перед элементом AY, но не обязательно рядом с ним. Переместить элементы, расположенные между данными элементами (включая данные элементы), в новый список (в том же порядке). Вывести ссылки на первые элементы преобразованного и нового списков. Если преобразованный список окажется пустым, то связанную с ним ссылку положить равной null. Новые объекты типа Node не создавать.

Dynamic54. Даны ссылки AX и AY на два различных элемента двусвязного списка; элемент AX находится в списке перед элементом AY, но не обязательно рядом с ним. Переместить элементы, расположенные между данными элементами (не включая данные элементы), в новый список (в том же порядке). Вывести ссылки на первые элементы преобразованного и нового списков. Если новый список окажется пустым, то связанную с ним ссылку положить равной null. Новые объекты типа Node не создавать.

Dynamic55. Дан первый элемент A1 непустого двусвязного списка. Преобразовать список в циклический, записав в свойство Next последнего элемента списка ссылку на его первый элемент, а в свойство Prev первого элемента — ссылку на последний элемент. Вывести ссылку на элемент, который был последним элементом исходного списка.

Dynamic56. Даны ссылки A1 и A2 на первый и последний элементы непустого двусвязного списка, содержащего четное количество элементов. Преобразовать список в два циклических списка (см. задание Dynamic55), первый из которых содержит первую половину элементов исходного списка, а второй — вторую половину. Вывести ссылки A3 и A4 на два средних элемента исходного списка (элемент A3 должен входить в первый циклический список, а элемент A4 — во второй). Новые объекты типа Node не создавать.

Dynamic57. Дано число K (> 0) и ссылки A1 и A2 на первый и последний элементы непустого двусвязного списка. Осуществить циклический сдвиг элементов списка на K позиций вперед (т. е. в направлении от начала к концу списка) и вывести ссылки на первый и последний элементы полученного списка. Для выполнения циклического сдвига преобразовать исходный список в циклический (см. задание Dynamic55), после чего «разорвать» его в позиции, соответствующей данному значению K. Новые объекты типа Node не создавать.

Dynamic58. Дано число K (> 0) и ссылки A1 и A2 на первый и последний элементы непустого двусвязного списка. Осуществить циклический сдвиг элементов списка на K позиций назад (т. е. в направлении от конца к началу списка) и вывести ссылки на первый и последний элементы полученного списка. Для выполнения циклического сдвига преобразовать исходный список в циклический (см. задание Dynamic55), после чего «разорвать» его в позиции, соответствующей данному значению K. Новые объекты типа Node не создавать.

Dynamic59. Даны ссылки A1, A2 и A3 на первый, последний и текущий элементы двусвязного списка (если список является пустым, то A1 = A2 = A3 = null). Также дано число N (> 0) и набор из N чисел. Описать класс IntList, содержащий следующие члены:

• три закрытых поля first, last, current типа Node (первый, последний и текущий элементы списка);
• конструктор с параметрами aFirst, aLast, aCurrent — первым, последним и текущим элементами существующего списка;
• процедура InsertLast(D), которая добавляет новый элемент со значением D в конец списка (D — входной параметр целого типа, добавленный элемент становится текущим);
• процедура Put (без параметров), которая выводит ссылки на поля first, last и current, используя метод Put класса PT.

С помощью метода InsertLast добавить в конец исходного списка данный набор чисел (в том же порядке) и вывести ссылки на первый, последний и текущий элементы полученного списка, используя для этого метод Put класса IntList.

Dynamic60. Даны ссылки A1, A2 и A3 на первый, последний и текущий элементы двусвязного списка (если список является пустым, то A1 = A2 = A3 = null). Также дано число N (> 0) и набор из N чисел. Включить в класс IntList (см. задание Dynamic59) процедуру InsertFirst(D), которая добавляет новый элемент со значением D в начало списка (D — входной параметр целого типа). Добавленный элемент становится текущим. С помощью метода InsertFirst добавить в начало исходного списка данный набор чисел (добавленные числа будут располагаться в списке в обратном порядке) и вывести ссылки на первый, последний и текущий элементы полученного списка.

Dynamic61. Даны ссылки A1, A2 и A3 на первый, последний и текущий элементы непустого двусвязного списка. Также даны пять чисел. Включить в класс IntList (см. задание Dynamic59) процедуру InsertBefore(D), которая вставляет новый элемент со значением D перед текущим элементом списка (D — входной параметр целого типа). Вставленный элемент становится текущим. С помощью метода InsertBefore вставить пять данных чисел в исходный список и вывести ссылки на первый, последний и текущий элементы полученного списка.

Dynamic62. Даны ссылки A1, A2 и A3 на первый, последний и текущий элементы непустого двусвязного списка. Также даны пять чисел. Включить в класс IntList (см. задание Dynamic59) процедуру InsertAfter(D), которая вставляет новый элемент со значением D после текущего элемента списка (D — входной параметр целого типа). Вставленный элемент становится текущим. С помощью метода InsertAfter вставить пять данных чисел в исходный список и вывести ссылки на первый, последний и текущий элементы полученного списка.

Dynamic63. Даны ссылки A1, A2 и A3 на первый, последний и текущий элементы непустого двусвязного списка. Включить в класс IntList (см. задание Dynamic59) процедуры ToFirst (делает текущим первый элемент списка), ToNext (делает текущим в списке следующий элемент, если он существует), SetData(D) (присваивает текущему элементу списка значение D целого типа), а также функцию IsLast логического типа (возвращает true, если текущий элемент списка является его последним элементом, и false в противном случае). Методы ToFirst, ToNext и IsLast не имеют параметров; параметр D метода SetData является входным параметром целого типа. С помощью данных методов присвоить нулевые значения элементам исходного списка с нечетными номерами и вывести количество элементов в списке, а также ссылки на первый, последний и текущий элементы преобразованного списка (текущим элементом должен стать последний элемент списка).

Dynamic64. Даны ссылки A1, A2 и A3 на первый, последний и текущий элементы непустого двусвязного списка. Включить в класс IntList (см. задание Dynamic59) процедуры ToLast (делает текущим последний элемент списка), ToPrev (делает текущим в списке предыдущий элемент, если он существует) и функции GetData целого типа (возвращает значение текущего элемента списка), IsFirst логического типа (возвращает true, если текущий элемент списка является его первым элементом, и false в противном случае). Данные методы не имеют параметров. С помощью этих методов вывести все четные значения элементов исходного списка, просматривая список с конца. Вывести также количество элементов в списке.

Dynamic65. Даны ссылки A1, A2 и A3 на первый, последний и текущий элементы двусвязного списка, содержащего не менее пяти элементов. Включить в класс IntList (см. задание Dynamic59) функцию DeleteCurrent целого типа (без параметров), удаляющую из списка текущий элемент и возвращающую его значение. После удаления элемента текущим становится следующий элемент или, если следующего элемента не существует, последний элемент списка. Метод DeleteCurrent также вызывает для удаленного элемента метод Dispose. С помощью метода DeleteCurrent удалить из исходного списка пять элементов и вывести их значения. Вывести также ссылки на первый, последний и текущий элементы преобразованного списка (для пустого списка вывести три константы null).

Dynamic66. Даны ссылки A1, A2 и A3 на первый, последний и текущий элементы непустого двусвязного списка. Включить в класс IntList (см. задание Dynamic59) классовый метод — процедуру Split(L1, L2), которая переносит элементы списка L1 от текущего до последнего в новый список L2 (таким образом, список L1 делится на две части, причем первая часть может оказаться пустой). Параметры процедуры имеют тип IntList; первый параметр является входным, второй — выходным. Текущими элементами непустых результирующих списков становятся их первые элементы. Новые объекты типа Node в процедуре Split не создавать. С помощью этой процедуры разбить исходный список на два и вывести ссылки на первый, последний и текущий элементы каждого из полученных списков (для пустого списка выводятся три константы null).

Dynamic67. Даны ссылки на первый, последний и текущий элементы двух непустых двусвязных списков. Включить в класс IntList (см. задание Dynamic59) классовый метод — процедуру Add(L1, L2), которая добавляет все элементы из списка L1 (в том же порядке) в конец списка L2; в результате список L1 становится пустым. Текущим элементом дополненного списка становится первый из добавленных элементов. Оба параметра процедуры имеют тип IntList и являются входными. Новые объекты типа Node в процедуре Add не создавать. С помощью этой процедуры добавить первый из данных списков в конец второго и вывести ссылки на первый, последний и текущий элементы объединенного списка.

Dynamic68. Даны ссылки на первый, последний и текущий элементы двух непустых двусвязных списков. Включить в класс IntList (см. задание Dynamic59) классовый метод — процедуру Insert(L1, L2), которая вставляет все элементы из списка L1 (в том же порядке) в список L2 перед его текущим элементом; в результате список L1 становится пустым. Текущим элементом списка L2 становится первый из вставленных элементов. Оба параметра процедуры имеют тип IntList и являются входными. Новые объекты типа Node в процедуре Insert не создавать. С помощью этой процедуры вставить первый из данных списков в текущую позицию второго и вывести ссылки на первый, последний и текущий элементы объединенного списка.

Dynamic69. Даны ссылки на первый, последний и текущий элементы двух двусвязных списков (второй список может быть пустым). Включить в класс IntList (см. задание Dynamic59) классовый метод — процедуру MoveCurrent(L1, L2), которая перемещает текущий элемент списка L1 в список L2 (элемент вставляется после текущего элемента списка L2 и сам становится текущим; в списке L1 текущим становится следующий элемент или, если следующего элемента не существует, последний элемент). Оба параметра процедуры имеют тип IntList и являются входными. Новые объекты типа Node в процедуре MoveCurrent не создавать. С помощью этой процедуры переместить текущий элемент первого списка во второй и вывести ссылки на первый, последний и текущий элементы каждого из полученных списков (для пустого списка выводятся три константы null).

Динамические структуры данных: список с барьерным элементом

Реализация двусвязного списка в виде цепочки узлов, ограниченной по краям нулевыми ссылками null, не является единственно возможной. Двусвязный список можно также реализовать в виде замкнутой цепочки узлов с дополнительным фиктивным, или барьерным, элементом. Этот барьерный элемент связан своими свойствами Next и Prev с первым и последним «настоящим» элементом списка соответственно, поэтому, имея ссылку на барьерный элемент, можно сразу перейти как к первому, так и к последнему элементу списка (естественно, первый и последний элементы также связаны с барьерным элементом своими свойствами Prev и Next соответственно). Для работы с двусвязным списком, снабженным барьерным элементом, достаточно хранить две ссылки: Barrier, указывающую на барьерный элемент, и Current, указывающую на текущий элемент (который может быть как «настоящим», так и барьерным элементом). Свойство Data барьерного элемента может быть произвольным; для определенности его можно положить равным 0. Пустой список в данной реализации представляет собой единственный барьерный элемент, «замкнутый на себя».

Задания данной подгруппы посвящены двусвязным спискам с барьерным элементом.

Dynamic70. Даны ссылки A1 и A2 на первый и последний элементы двусвязного списка, реализованного в виде цепочки узлов, которая ограничена по краям константами null (если список пуст, то A1 = A2 = null). Преобразовать исходный список в циклический список (см. задание Dynamic55), снабженный барьерным элементом. Барьерный элемент должен иметь значение 0 и быть связан своими свойствами Next и Prev с первым и последним элементом исходного списка (в случае пустого исходного списка свойства Next и Prev барьерного элемента должны указывать на сам барьерный элемент). Вывести ссылку на барьерный элемент полученного списка. Не создавать новые объекты типа Node, за исключением барьерного элемента.

Dynamic71. Даны ссылки A1 и A2 на барьерный и текущий элементы двусвязного списка (о списке с барьерным элементом см. задание Dynamic70). Разбить список на два, перенеся во второй список все элементы от текущего до последнего и добавив ко второму списку барьерный элемент. Если текущий элемент исходного списка является барьерным элементом, то второй список должен быть пустым (т. е. состоять только из барьерного элемента). Вывести ссылку на барьерный элемент второго списка. Не создавать новые объекты типа Node, за исключением барьерного элемента для второго списка.

Dynamic72. Даны ссылки A1 и A2 на барьерные элементы двух двусвязных списков (о списке с барьерным элементом см. задание Dynamic70). Объединить исходные списки, связав конец первого и начало второго списка (барьерным элементом объединенного списка должен остаться барьерный элемент первого списка). Вывести ссылки на первый и последний элементы объединенного списка (если объединенный список является пустым, то дважды вывести ссылку на его барьерный элемент). После удаления лишнего барьерного элемента вызвать для него метод Dispose.

Dynamic73. Даны ссылки A1 и A2 на барьерные элементы двух двусвязных списков (о списке с барьерным элементом см. задание Dynamic70). Объединить исходные списки, связав конец первого и начало второго списка (барьерным элементом объединенного списка должен остаться барьерный элемент второго списка). Вывести ссылки на первый и последний элементы объединенного списка (если объединенный список является пустым, то дважды вывести ссылку на его барьерный элемент). После удаления лишнего барьерного элемента вызвать для него метод Dispose.

Dynamic74. Даны ссылки A1 и A2 на барьерный и текущий элементы двусвязного списка (о списке с барьерным элементом см. задание Dynamic70). Также дано число N (> 0) и набор из N чисел. Описать класс IntListB, содержащий следующие члены:

• закрытые поля barrier и current типа Node (барьерный и текущий элементы списка);
• конструктор с параметрами aBarrier и aCurrent — барьерным и текущим элементами существующего списка;
• процедура InsertLast(D), которая добавляет новый элемент со значением D в конец списка (D — входной параметр целого типа, добавленный элемент становится текущим);
• процедура Put (без параметров), которая выводит ссылку на поле current, используя метод Put класса PT.

С помощью метода InsertLast добавить в конец исходного списка данный набор чисел (в том же порядке) и вывести сссылку на текущий элемент полученного списка, используя для этого метод Put класса IntListB.

Dynamic75. Даны ссылки A1 и A2 на барьерный и текущий элементы двусвязного списка. Также дано число N (> 0) и набор из N чисел. Включить в класс IntListB (см. задание Dynamic74) процедуру InsertFirst(D), которая добавляет новый элемент со значением D в начало списка (D — входной параметр целого типа). Добавленный элемент становится текущим. С помощью метода InsertFirst добавить в начало исходного списка данный набор чисел (добавленные числа будут располагаться в списке в обратном порядке) и вывести ссылку на текущий элемент полученного списка.

Dynamic76. Даны ссылки A1 и A2 на барьерный и текущий элементы двусвязного списка. Также даны пять чисел. Включить в класс IntListB (см. задание Dynamic74) процедуру InsertBefore(D), которая вставляет новый элемент со значением D перед текущим элементом списка (D — входной параметр целого типа). Вставленный элемент становится текущим. С помощью метода InsertBefore вставить пять данных чисел в исходный список и вывести ссылку на текущий элемент полученного списка.

Dynamic77. Даны ссылки A1 и A2 на барьерный и текущий элементы двусвязного списка. Также даны пять чисел. Включить в класс IntListB (см. задание Dynamic74) процедуру InsertAfter(D), которая вставляет новый элемент со значением D после текущего элемента списка (D — входной параметр целого типа). Вставленный элемент становится текущим. С помощью метода InsertAfter вставить пять данных чисел в исходный список и вывести ссылку на текущий элемент полученного списка.

Dynamic78. Даны ссылки A1 и A2 на барьерный и текущий элементы двусвязного списка. Включить в класс IntListB (см. задание Dynamic74) процедуры ToFirst (делает текущим первый элемент списка), ToNext (делает текущим следующий элемент в списке), SetData(D) (присваивает текущему элементу списка значение D целого типа, если данный элемент не является барьерным) и функцию IsBarrier логического типа (возвращает true, если текущий элемент списка является его барьерным элементом, и false в противном случае). Методы ToFirst, ToNext и IsBarrier не имеют параметров. Параметр D метода SetData является входным параметром целого типа. С помощью этих методов присвоить нулевые значения элементам исходного списка с нечетными номерами и вывести количество элементов в списке, а также ссылку на новый текущий элемент списка (текущим элементом списка должен стать его барьерный элемент). Нумерация ведется от первого элемента списка; барьерный элемент не нумеруется и не учитывается при подсчете элементов.

Dynamic79. Даны ссылки A1 и A2 на барьерный и текущий элементы двусвязного списка. Включить в класс IntListB (см. задание Dynamic74) процедуры ToLast (делает текущим последний элемент списка), ToPrev (делает текущим предыдущий элемент в списке) и функцию GetData целого типа (возвращает значение текущего элемента списка L). Данные методы не имеют параметров. С помощью этих методов, а также функции IsBarrier из задания Dynamic78, вывести все четные значения элементов исходного списка, просматривая список с конца. Вывести также количество элементов в списке. Барьерный элемент не обрабатывается и не учитывается при подсчете элементов.

Dynamic80. Даны ссылки A1 и A2 на барьерный и текущий элементы непустого двусвязного списка, причем текущий элемент не совпадает с барьерным. Включить в класс IntListB (см. задание Dynamic74) функцию DeleteCurrent целого типа, удаляющую из списка текущий элемент и возвращающую его значение. Текущим становится следующий элемент или, если следующий элемент является барьерным, предыдущий элемент списка. Функция также вызывает для удаленного элемента метод Dispose. Если текущим элементом является барьерный элемент, то функция не выполняет никаких действий и возвращает 0. С помощью этой функции, а также метода IsBarrier из задания Dynamic78, удалить из исходного списка пять элементов (или все элементы, если их менее пяти) и вывести их значения. Вывести также ссылку на новый текущий элемент списка.


Группы заданий

Деревья: группа Tree

Все числа, используемые в заданиях на деревья, являются целыми. Все указатели имеют тип PNode и указывают на записи типа TNode; типы PNode и TNode определены в задачнике Programming Taskbook. В заданиях на деревья используются поля Data, Left, Right и Parent записей типа TNode, поэтому при выполнении этих заданий можно считать, что типы PNode и TNode описаны следующим образом:

[Pascal]

type
PNode = ^TNode;
TNode = record
Data: integer;
Left: PNode;
Right: PNode;
Parent: PNode;
end;

[C++]

struct TNode
{
int Data;
TNode* Left;
TNode* Right;
TNode* Parent;
};
typedef TNode* PNode;

В большинстве заданий при работе с записями типа TNode требуются только поля Data, Left и Right; поле Parent используется лишь в заданиях на обработку дереьев с обратной связью.

Значением вершины дерева (т. е. записи типа TNode) считается значение его поля Data.

Так как переменные типа «указатель» предназначены для хранения адресов, в формулировках заданий слова «указатель» (на вершину дерева) и «адрес» (вершины дерева) используются как синонимы.

В программах на языке C++ для освобождения динамической памяти, связанной с указателем p типа PNode, следует использовать функцию DeleteNode(p).

Анализ бинарного дерева

Tree1. Дан адрес P1 записи типа TNode с полями Data (целого типа), Left и Right (типа PNode — указателя на TNode). Эта запись (корень дерева) связана полями Left и Right с записями того же типа (левой и правой дочерней вершиной). Вывести значения полей Data корня, его левой и правой дочерних вершин, а также адреса левой и правой дочерних вершин в указанном порядке.

Tree2. Дан адрес P1 записи типа TNode — корня дерева. Эта запись связана полями Left и Right с другими записями того же типа (дочерними вершинами), они, в свою очередь, — со своими дочерними вершинами, и так далее до записей, поля Left и Right которых равны nil (у некоторых вершин может быть равно nil одно из полей — Left или Right). Вывести количество вершин дерева.

Tree3. Дан указатель P1 на корень непустого дерева и число K. Вывести количество вершин дерева, значение которых равно K.

Tree4. Дан указатель P1 на корень непустого дерева. Вывести сумму значений всех вершин данного дерева.

Tree5. Дан указатель P1 на корень непустого дерева. Вывести количество вершин дерева, являющихся левыми дочерними вершинами (корень дерева не учитывать).

Tree6. Дан указатель P1 на корень непустого дерева. Листом дерева называется его вершина, не имеющая дочерних вершин. Вывести количество листьев для данного дерева.

Tree7. Дан указатель P1 на корень непустого дерева. Вывести сумму значений всех листьев данного дерева.

Tree8. Дан указатель P1 на корень дерева, содержащего по крайней мере две вершины. Вывести количество листьев дерева, являющихся правыми дочерними вершинами.

Tree9. Дан указатель P1 на корень непустого дерева. Считается, что корень дерева находится на нулевом уровне, его дочерние вершины — на первом уровне и т. д. Вывести глубину дерева, т. е. значение его максимального уровня (например, глубина дерева, состоящего только из корня, равна 0).

Tree10. Дан указатель P1 на корень непустого дерева. Для каждого из уровней данного дерева, начиная с нулевого, вывести количество вершин, находящихся на этом уровне. Считать, что глубина дерева не превосходит 10.

Tree11. Дан указатель P1 на корень непустого дерева. Для каждого из уровней данного дерева, начиная с нулевого, вывести сумму значений вершин, находящихся на этом уровне. Считать, что глубина дерева не превосходит 10.

Tree12. Дан указатель P1 на корень непустого дерева. Вывести значения всех вершин дерева в инфиксном порядке (вначале выводится содержимое левого поддерева в инфиксном порядке, затем выводится значение корня, затем — содержимое правого поддерева в инфиксном порядке).

Tree13. Дан указатель P1 на корень непустого дерева. Вывести значения всех вершин дерева в префиксном порядке (вначале выводится значение корня, затем содержимое левого поддерева в префиксном порядке, затем — содержимое правого поддерева в префиксном порядке).

Tree14. Дан указатель P1 на корень непустого дерева. Вывести значения всех вершин дерева в постфиксном порядке (вначале выводится содержимое левого поддерева в постфиксном порядке, затем — содержимое правого поддерева в постфиксном порядке, затем — значение корня).

Tree15. Дан указатель P1 на корень непустого дерева и число N (> 0), не превосходящее количество вершин в исходном дереве. Нумеруя вершины в инфиксном порядке (см. задание Tree12, нумерация ведется от 1), вывести значения всех вершин с порядковыми номерами от 1 до N.

Tree16. Дан указатель P1 на корень непустого дерева и число N (> 0), не превосходящее количество вершин в исходном дереве. Нумеруя вершины в постфиксном порядке (см. задание Tree14, нумерация ведется от 1), вывести значения всех вершин с порядковыми номерами от N до максимального номера.

Tree17. Дан указатель P1 на корень непустого дерева и два числа N1, N2 (0 < N1 < N2), которые не превосходят количество вершин в исходном дереве. Нумеруя вершины в префиксном порядке (см. задание Tree13, нумерация ведется от 1), вывести значения всех вершин с порядковыми номерами от N1 до N2.

Tree18. Дан указатель P1 на корень непустого дерева и неотрицательное число L. Используя любой из описанных в заданиях Tree12−Tree14 способов обхода дерева, вывести значения всех вершин уровня L, а также их количество N (если дерево не содержит вершин уровня L, то вывести 0).

Tree19. Дан указатель P1 на корень непустого дерева. Вывести максимальное из значений его вершин и количество вершин, имеющих это максимальное значение.

Tree20. Дан указатель P1 на корень непустого дерева. Вывести минимальное из значений всех его вершин и количество листьев, имеющих это минимальное значение (данное количество может быть равно 0).

Tree21. Дан указатель P1 на корень непустого дерева. Вывести минимальное из значений его вершин, являющихся листьями.

Tree22. Дан указатель P1 на корень дерева, содержащего по крайней мере две вершины. Вывести максимальное из значений его внутренних вершин (т. е. вершин, не являющихся листьями).

Tree23. Дан указатель P1 на корень непустого дерева. Вывести указатель P2 на первую вершину дерева с минимальным значением (вершины перебирать в префиксном порядке).

Tree24. Дан указатель P1 на корень непустого дерева. Вывести указатель P2 на последнюю вершину дерева с максимальным нечетным значением (вершины перебирать в инфиксном порядке). Если дерево не содержит вершин с нечетными значениями, то вывести nil.

Формирование бинарного дерева

Tree25. Дано число N (> 0) и набор из N чисел. Создать дерево из N вершин, в котором каждая вершина (кроме корня) является правой дочерней вершиной. Каждой создаваемой вершине присваивать очередное значение из исходного набора. Вывести указатель на корень созданного дерева.

Tree26. Дано число N (> 0) и набор из N чисел. Создать дерево из N вершин, в котором каждая внутренняя вершина имеет только одну дочернюю вершину, причем правые и левые дочерние вершины чередуются (корень имеет левую дочернюю вершину). Каждой создаваемой вершине присваивать очередное значение из исходного набора. Вывести указатель на корень созданного дерева.

Tree27. Дано число N (> 0) и набор из N чисел. Создать дерево из N вершин, в котором каждая внутренняя вершина имеет только одну дочернюю вершину, причем если значение вершины является нечетным, то она имеет левую дочернюю вершину, а если четным, то правую. Каждой создаваемой вершине присваивать очередное значение из исходного набора. Вывести указатель на корень созданного дерева.

Tree28. Дано четное число N (> 0) и набор из N чисел. Создать дерево из N вершин, в котором каждая левая дочерняя вершина является листом, а правая дочерняя вершина является внутренней. Для каждой внутренней вершины вначале создавать левую дочернюю вершину, а затем правую (если она существует); каждой создаваемой вершине присваивать очередное значение из исходного набора. Вывести указатель на корень созданного дерева.

Tree29. Дано четное число N (> 0) и набор из N чисел. Создать дерево из N вершин со следующей структурой: если вершина дерева является внутренней, то в случае, если она имеет нечетное значение, ее левая дочерняя вершина должна быть листом, а в случае, если она имеет четное значение, листом должна быть ее правая вершина. Для каждой внутренней вершины вначале создавать дочернюю вершину-лист, а затем дочернюю внутреннюю вершину (если данная вершина существует); каждой создаваемой вершине присваивать очередное значение из исходного набора. Вывести указатель на корень созданного дерева.

Tree30. Дано число N (> 0). Создать дерево, корень которого имеет значение N, а вершины обладают следующими свойствами: вершина с четным значением K имеет левую дочернюю вершину со значением K/2 и не имеет правой дочерней вершины; вершина со значением 1 является листом; вершина с любым другим нечетным значением K имеет две дочерние вершины: левую со значением K/2 и правую со значением K − K/2 (символ «/» обозначает операцию деления нацело). Вывести указатель на корень созданного дерева.

Tree31. Даны положительные числа L, N (N > L) и набор из N чисел. Создать дерево глубины L, содержащее вершины со значениями из исходного набора. Вершины добавлять к дереву в префиксном порядке, используя алгоритм, который для каждой вершины уровня, не превышающего L, вначале создает саму вершину с очередным значением из исходного набора, затем ее левое поддерево соответствующей глубины, а затем ее правое поддерево. Если для заполнения дерева глубины L требуется менее N вершин, то оставшиеся числа из исходного набора не использовать. Вывести указатель на корень созданного дерева.

Tree32. Дано число N (> 0) и набор из N чисел. Создать идеально сбалансированное дерево из N вершин с заданными значениями (т. е. дерево, для каждой вершины которого количество вершин в его левом и правом поддереве отличается не более чем на 1) и вывести указатель на его корень. Для создания дерева использовать рекурсивный алгоритм, который создает вершину дерева с очередным значением, после чего вызывается для создания левого поддерева с N/2 вершинами и правого поддерева с N − 1 − N/2 вершинами (символ «/» обозначает операцию деления нацело).

Tree33. Дано число N (> 0). Создать идеально сбалансированное дерево из N вершин и вывести указатель на его корень. Значение каждой вершины положить равным уровню этой вершины (например, корень дерева должен иметь значение 0, его дочерние вершины — значение 1 и т. д.). При формировании дерева использовать алгоритм, описанный в задании Tree32.

Tree34. Дан указатель P1 на корень непустого дерева. Создать копию данного дерева и вывести указатель P2 на корень созданной копии.

Преобразование бинарного дерева

Tree35. Дан указатель P1 на корень непустого дерева. Удвоить значение каждой вершины дерева.

Tree36. Дан указатель P1 на корень непустого дерева. Для каждой вершины дерева с четным значением уменьшить ее значение в два раза.

Tree37. Дан указатель P1 на корень непустого дерева. Добавить 1 к значению каждого листа дерева и вычесть 1 из значения каждой внутренней вершины.

Tree38. Дан указатель P1 на корень непустого дерева. Для каждой вершины дерева, имеющей две дочерние вершины, поменять местами значения дочерних вершин (т. е. значения их полей Data).

Tree39. Дан указатель P1 на корень непустого дерева. Для всех внутренних вершин дерева поменять местами их левые и правые дочерние вершины (т. е. значения полей Left и Right).

Tree40. Дан указатель P1 на корень непустого дерева. Удалить из дерева все вершины, кроме корня, и освободить память, которую занимали удаленные вершины (полям Left и Right корня следует присвоить значение nil).

Tree41. Дан указатель P1 на корень дерева, содержащего по крайней мере две вершины. Удалить каждую вершину дерева, являющуюся листом; при этом соответствующее поле родительской вершины (Left или Right) следует положить равным nil. При удалении вершин освобождать память, которую они занимали.

Tree42. Дан указатель P1 на корень непустого дерева. Удалить вершины дерева, имеющие значения, меньшие значения корня, вместе со всеми их дочерними вершинами. При удалении вершин освобождать память, которую они занимали.

Tree43. Дан указатель P1 на корень непустого дерева. Для вершин дерева, имеющих две дочерние вершины, удалить одну из дочерних вершин: правую, если родительская вершина имеет четное значение, и левую в противном случае (вершины дерева перебирать в префиксном порядке, при удалении вершины удалять и всех ее потомков). Для удаленных вершин освобождать память, которую они занимали.

Tree44. Дан указатель P1 на корень непустого дерева. Ко всем вершинам дерева, которые являются листьями, добавить по две дочерние вершины-листа: левую со значением 10 и правую со значением 11.

Tree45. Дан указатель P1 на корень непустого дерева. Ко всем вершинам дерева, которые являются листьями, добавить по одной дочерней вершине-листу; при этом к исходной вершине с нечетным значением добавляется левая дочерняя вершина, а к вершине с четным значением — правая. Значение каждой добавленной вершины положить равным значению ее родительской вершины.

Tree46. Дан указатель P1 на корень непустого дерева. Ко всем вершинам дерева, которые содержат ровно по одной дочерней вершине, добавить еще одну дочернюю вершину-лист. Значение каждой добавленной вершины положить равным удвоенному значению ее родительской вершины.

Tree47. Дан указатель P1 на корень непустого дерева. Не изменяя глубины L исходного дерева, дополнить его до полного дерева, т. е. дерева, все листья которого находятся на уровне L. Значения всех добавленных вершин положить равными −1.

Бинарные деревья с обратной связью

Tree48. Дан адрес P1 вершины дерева — записи типа TNode, содержащей поля Data (целого типа), Left, Right и Parent (типа PNode — указателя на TNode). Поля Left и Right указывают на дочерние вершины, а поле Parent — на родительскую вершину данной вершины (если вершина является корнем дерева, то ее поле Parent равно nil). Для данной вершины вывести указатели PL, PR и P0 на ее левую и правую дочерние вершины и родительскую вершину, а также указатель P2 на ее сестру, т. е. другую вершину дерева, имеющую в качестве родительской вершину с адресом P0. Если некоторые из перечисленных вершин не существуют, то вывести для них значение nil.

Tree49. Дан указатель P1 на корень дерева, вершинами которого являются записи типа TNode, связанные между собой с помощью полей Left и Right. Используя поле Parent записи TNode, преобразовать исходное дерево в дерево с обратной связью, в котором каждая вершина связана не только со своими дочерними вершинами (полями Left и Right), но и с родительской вершиной (полем Parent). Поле Parent корня дерева положить равным nil.

Tree50. Дан указатель P1 на одну из вершин дерева с обратной связью. Вывести указатель P2 на корень исходного дерева.

Tree51. Даны указатели P1, P2, P3 на три вершины дерева с обратной связью. Для каждой из данных вершин вывести ее уровень (корень дерева имеет уровень 0).

Tree52. Даны указатели P1 и P2 на две различные вершины дерева с обратной связью. Вывести степень родства вершины P1 по отношению к вершине P2 (степень родства равна −1, если вершина P2 не находится в цепочке предков для вершины P1; в противном случае степень родства равна L1 − L2, где L1 и L2 — уровни вершин P1 и P2 соответственно).

Tree53. Даны указатели P1 и P2 на две различные вершины дерева с обратной связью. Вывести указатель P0 на вершину дерева, являющуюся ближайшим общим предком вершин P1 и P2.

Tree54. Дан указатель P1 на одну из вершин дерева с обратной связью. Создать копию данного дерева и вывести указатель P2 на корень созданной копии.

Tree55. Дан указатель P1 на вершину дерева с обратной связью, которая не является корнем. Если вершина P1 имеет сестру, то удалить эту сестру вместе со всеми ее потомками, освободив занимаемую ими память; если вершина P1 не имеет сестры, то создать сестру и всех ее потомков в виде копии поддерева с корнем P1. Вывести указатель P0 на родительскую вершину вершины P1.

Tree56. Даны положительные числа L, N (N > L) и набор из N чисел. Создать дерево глубины L с обратной связью, содержащее вершины со значениями из исходного набора. Вершины добавлять к дереву в префиксном порядке, используя алгоритм, который для каждой вершины уровня, не превышающего L, вначале создает саму вершину с очередным значением из исходного набора, затем ее левое поддерево соответствующей глубины, а затем ее правое поддерево. Если для заполнения дерева глубины L требуется менее N вершин, то оставшиеся числа из исходного набора не использовать. Вывести указатель на корень созданного дерева.

Бинарные деревья поиска

Tree57. Дан указатель P1 на корень непустого дерева. Если данное дерево является деревом поиска, т. е. если при обходе его вершин в инфиксном порядке их значения образуют неубывающую последовательность, то вывести nil; в противном случае вывести адрес первой вершины (в инфиксном порядке), нарушающей требуемую закономерность.

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

Tree59. Дан указатель P1 на корень непустого дерева поиска без повторяющихся элементов и число K. Определить, содержит ли исходное дерево вершину со значением K. Если содержит, то вывести указатель P2 на эту вершину, в противном случае вывести nil. Вывести также количество N вершин, которые потребовалось проанализировать для выполнения задания.

Tree60. Дан указатель P1 на корень непустого дерева поиска и число K. Вывести количество C вершин исходного дерева, имеющих значение K, а также количество N вершин, которые потребовалось проанализировать для выполнения задания.

Tree61. Дан указатель P1 на корень дерева поиска (если дерево является пустым, то P1 = nil). Также дано число K. Добавить к исходному дереву поиска новую вершину со значением K таким образом, чтобы полученное дерево осталось деревом поиска, и вывести указатель P2 на корень полученного дерева. Использовать следующий рекурсивный алгоритм для дерева с корнем P: если P = nil, то создать лист со значением K и присвоить указателю P адрес созданного листа; если корень P существует, то в случае, если его значение больше K, выполнить алгоритм для поля Left корня P, иначе выполнить алгоритм для его поля Right.

Tree62. Дан указатель P1 на корень дерева поиска без повторяющихся элементов (если дерево является пустым, то P1 = nil). Также дано число K. Добавить к исходному дереву поиска новую вершину со значением K таким образом, чтобы полученное дерево осталось деревом поиска без повторяющихся элементов, и вывести указатель P2 на корень полученного дерева. Если исходное дерево уже содержит вершину со значением K, то оставить дерево без изменений. Использовать следующий рекурсивный алгоритм для дерева с корнем P: если P = nil, то создать лист со значением K и присвоить указателю P адрес созданного листа; если корень P существует, то в случае, если его значение больше K, выполнить алгоритм для поля Left корня P, а в случае, если его значение меньше K, выполнить алгоритм для его поля Right.

Tree63. Дано число N (> 0) и набор из N чисел, а также указатель P1 на корень дерева поиска (если дерево является пустым, то P1 = nil). Добавить к исходному дереву поиска N новых вершин со значениями из исходного набора таким образом, чтобы полученное дерево осталось деревом поиска, и вывести указатель P2 на корень полученного дерева. Для добавления новых вершин использовать алгоритм, описанный в задании Tree61.

Tree64. Дано число N (> 0) и набор из N чисел, а также указатель P1 на корень дерева поиска без повторяющихся элементов (если дерево является пустым, то P1 = nil). Добавить к исходному дереву поиска новые вершины со значениями из исходного набора таким образом, чтобы полученное дерево осталось деревом поиска без повторяющихся элементов, и вывести указатель P2 на корень полученного дерева. Для добавления новых вершин использовать алгоритм, описанный в задании Tree62.

Tree65. Дано число N (> 0) и набор из N чисел. Отсортировать исходный набор чисел, создав для него дерево поиска (алгоритм добавления вершин к дереву поиска описан в задании Tree61). Вывести указатель P1 на корень полученного дерева, а также отсортированный набор чисел (для вывода набора чисел выполнить перебор вершин дерева в инфиксном порядке).

Tree66. Дано число N (> 0) и набор из N чисел. Получить отсортированный набор исходных чисел без повторений, создав для исходного набора дерево поиска без повторяющихся элементов (алгоритм добавления вершин к подобному дереву описан в задании Tree62). Вывести указатель P1 на корень полученного дерева, а также отсортированный набор чисел без повторений (для вывода набора чисел выполнить перебор вершин дерева в инфиксном порядке).

Tree67. Даны два указателя: P1 на корень непустого дерева поиска и P2 на одну из вершин этого дерева, имеющих не более одной дочерней вершины. Удалить из исходного дерева вершину с адресом P2 так, чтобы полученное дерево осталось деревом поиска (если удаляемая вершина P2 имеет дочернюю вершину, то эту дочернюю вершину необходимо связать с родительской вершиной вершины P2). Вывести указатель P3 на корень полученного дерева или nil, если в результате удаления вершины P2 дерево стало пустым.

Tree68. Даны два указателя: P1 на корень непустого дерева поиска и P2 на одну из вершин этого дерева, имеющих две дочерние вершины. Удалить из исходного дерева вершину P2 так, чтобы полученное дерево осталось деревом поиска. Удаление выполнять следующим образом: в левом поддереве вершины P2 найти вершину P с наибольшим значением, присвоить это наибольшее значение вершине P2, после чего удалить вершину P, действуя, как в задании Tree67 (поскольку вершина P будет иметь не более одной дочерней вершины).

Tree69. Даны два указателя: P1 на корень непустого дерева поиска и P2 на одну из вершин этого дерева, имеющих две дочерние вершины. Удалить из исходного дерева вершину P2 так, чтобы полученное дерево осталось деревом поиска. Удаление выполнять следующим образом: в правом поддереве вершины P2 найти вершину P с наименьшим значением, присвоить это наименьшее значение вершине P2, после чего удалить вершину P, действуя, как в задании Tree67 (поскольку вершина P будет иметь не более одной дочерней вершины).

Tree70. Дан указатель P1 на одну из вершин непустого дерева поиска с обратной связью. Удалить из исходного дерева вершину P1 таким образом, чтобы полученное дерево осталось деревом поиска с обратной связью, и вывести указатель P2 на корень полученного дерева или nil, если в результате удаления дерево стало пустым. Если вершина P1 имеет две дочерние вершины, то для ее удаления использовать алгоритм, описанный в задании Tree68.

Tree71. Дан указатель P1 на одну из вершин непустого дерева поиска с обратной связью. Удалить из исходного дерева вершину P1 таким образом, чтобы полученное дерево осталось деревом поиска с обратной связью, и вывести указатель P2 на корень полученного дерева или nil, если в результате удаления дерево стало пустым. Если вершина P1 имеет две дочерние вершины, то для ее удаления использовать алгоритм, описанный в задании Tree69.

Бинарные деревья разбора выражений

Tree72. Дана строка S, содержащая описание непустого дерева в следующем формате:

<дерево> | ::= | <пусто> |
 |  | <вершина>(<левое поддерево>,<правое поддерево>)
<вершина> | ::= | <цифра>

Например, «4(2(,),6(,7(3(,),)))» (пробелы отсутствуют). Создать дерево по описанию, приведенному в S, и вывести указатель на его корень.

Tree73. Дан указатель P1 на корень непустого дерева. Вывести строку с описанием исходного дерева в формате, приведенном в задании Tree72.

Tree74. Дана строка S, содержащая описание непустого дерева в следующем формате:

<дерево> | ::= | <вершина> |
 |  | <вершина>(<левое поддерево>,<правое поддерево>) |
 |  | <вершина>(<левое поддерево>) |
 |  | <вершина>(,<правое поддерево>)
<вершина> | ::= | <цифра>

Например, «4(2,6(,7(3)))» (пробелы отсутствуют, вид описания вершины зависит от того, имеет ли вершина непустое левое и/или правое поддерево). Создать дерево по описанию, приведенному в S, и вывести указатель на его корень.

Tree75. Дан указатель P1 на корень непустого дерева. Вывести строку с описанием исходного дерева в формате, приведенном в задании Tree74.

Tree76. Дана строка S, содержащая описание числового выражения в следующем формате:

<выражение> | ::= | <цифра> |
 |  | (<выражение><знак><выражение>)
<знак> | ::= | + | − | *

Пробелы в строке отсутствуют. Создать дерево, соответствующее исходному выражению (дерево разбора выражения): каждая внутренняя вершина дерева должна соответствовать одной из трех возможных арифметических операций и иметь значение −1 для операции сложения, −2 для операции вычитания и −3 для операции умножения; левое и правое дочерние поддеревья любой внутренней вершины-операции должны соответствовать выражениям слева и справа от знака операции; листьями полученного дерева должны быть выражения-цифры. Вывести указатель на корень созданного дерева.

Tree77. Дана строка S, содержащая описание числового выражения в следующем формате (так называемый префиксный бесскобочный формат записи числового выражения):

<выражение> | ::= | <цифра> |
 |  | <знак> <выражение> <выражение>
<знак> | ::= | + | − | *

Выражения отделяются друг от друга и от знаков операций ровно одним пробелом. Создать дерево разбора выражения и вывести указатель на его корень. Структура дерева разбора выражения описана в задании Tree76; для каждой вершины-операции ее левое поддерево должно соответствовать первому операнду данной операции, а правое поддерево — второму.

Tree78. Дана строка S, содержащая описание числового выражения в следующем формате (так называемый постфиксный бесскобочный формат записи числового выражения):

<выражение> | ::= | <цифра> |
 |  | <выражение> <выражение> <знак>
<знак> | ::= | + | − | *

Выражения отделяются друг от друга и от знаков операций ровно одним пробелом. Создать дерево разбора выражения и вывести указатель на его корень. Структура дерева разбора выражения описана в задании Tree76; для каждой вершины-операции ее левое поддерево должно соответствовать первому операнду данной операции, а правое поддерево — второму.

Tree79. Дан указатель P1 на корень непустого дерева разбора выражения (структура дерева описана в задании Tree76). Вывести значение выражения, определяемого исходным деревом.

Tree80. Дан указатель P1 на корень непустого дерева разбора выражения (структура дерева описана в задании Tree76). Вывести строковое представление соответствующего выражения в формате, приведенном в том же задании:

<выражение> | ::= | <цифра> |
 |  | (<выражение><знак><выражение>)
<знак> | ::= | + | − | *

Tree81. Дан указатель P1 на корень непустого дерева разбора выражения. Вывести строковое представление соответствующего выражения в префиксном бесскобочном формате (см. задание Tree77).

Tree82. Дан указатель P1 на корень непустого дерева разбора выражения. Вывести строковое представление соответствующего выражения в постфиксном бесскобочном формате (см. задание Tree78).

Tree83. Дана строка S, содержащая описание числового выражения в следующем формате (функция M возвращает максимальное из двух выражений, а m — минимальное):

<выражение> | ::= | <цифра> | M(<выражение> , <выражение>) |
 |  | m(<выражение> , <выражение>)

Пробелы в строке отсутствуют. Создать дерево разбора исходного выражения: каждая внутренняя вершина дерева должна соответствовать одной из двух возможных функций и иметь значение −1 для функции M и −2 для функции m; для каждой вершины-функции ее левое поддерево должно соответствовать первому аргументу функции, а правое поддерево — второму; листьями полученного дерева должны быть выражения-цифры. Вывести указатель на корень созданного дерева.

Tree84. Дан указатель P1 на корень непустого дерева разбора выражения (структура дерева описана в задании Tree83). Вывести значение выражения, определяемого исходным деревом.

Tree85. Дан указатель P1 на корень непустого дерева разбора выражения (структура дерева описана в задании Tree83). Вывести строковое представление соответствующего выражения в формате, приведенном в том же задании:

<выражение> | ::= | <цифра> | M(<выражение> , <выражение>) |
 |  | m(<выражение> , <выражение>)

Деревья общего вида

Tree86. Дерево общего вида (каждая вершина которого может иметь произвольное число дочерних вершин, расположенных в фиксированном порядке в направлении слева направо) реализуется с помощью набора связанных записей типа TNode следующим образом: для каждой внутренней вершины ее поле Left содержит указатель на ее первую (т. е. левую) дочернюю вершину, а поле Right — указатель на ее правую сестру, т. е. вершину, имеющую в дереве общего вида того же родителя. Поле Right корня дерева общего вида всегда равно nil, так как корень сестер не имеет. Дан указатель P1 на корень непустого бинарного дерева. Создать дерево общего вида, соответствующее исходному бинарному дереву, и вывести указатель P2 на его корень.

Tree87. Дан указатель P1 на корень непустого дерева общего вида. Любая вершина исходного дерева имеет не более двух дочерних вершин. Создать бинарное дерево, соответствующее исходному дереву общего вида, и вывести указатель P2 на его корень. Считать, что первая дочерняя вершина любой вершины дерева общего вида соответствует левой дочерней вершине в бинарном дереве.

Tree88. Дан указатель P1 на корень непустого дерева общего вида. Вывести глубину данного дерева, т. е. значение его максимального уровня, считая, что все вершины-сестры находятся на одном уровне, а корень дерева расположен на уровне 0.

Tree89. Дан указатель P1 на корень непустого дерева общего вида. Для каждого из уровней данного дерева, начиная с уровня 0, вывести количество вершин, находящихся на этом уровне. Считать, что глубина дерева общего вида не превосходит 10.

Tree90. Дан указатель P1 на корень непустого дерева общего вида. Для каждого из уровней данного дерева, начиная с уровня 0, вывести сумму значений вершин, находящихся на этом уровне. Считать, что глубина дерева общего вида не превосходит 10.

Tree91. Дан указатель P1 на корень непустого дерева общего вида. Также дано неотрицательное число L. Перебирая дочерние вершины в заданном порядке (т. е. слева направо), вывести значения всех вершин уровня L и их количество N. Если дерево не содержит вершин уровня L, то вывести 0.

Tree92. Дан указатель P1 на корень непустого дерева общего вида. Вывести значения всех вершин дерева в инфиксном порядке: вначале выводится содержимое первого (левого) поддерева в инфиксном порядке, затем выводится значение корня, а затем — содержимое остальных поддеревьев в инфиксном порядке (поддеревья перебираются слева направо).

Tree93. Дан указатель P1 на корень непустого дерева общего вида. Вывести значения всех вершин дерева в постфиксном порядке: вначале выводится содержимое каждого поддерева в постфиксном порядке (поддеревья перебираются слева направо), а затем — значение корня.

Tree94. Дан указатель P1 на корень непустого дерева общего вида. Также дано неотрицательное число N. Вывести количество вершин исходного дерева, имеющих ровно N дочерних вершин. Если требуемые вершины отсутствуют, то вывести 0.

Tree95. Дан указатель P1 на корень непустого дерева общего вида. Вывести указатель P2 на первую вершину дерева, имеющую наибольшее количество дочерних вершин. Вершины перебирать в инфиксном порядке (см. задание Tree92).

Tree96. Дан указатель P1 на корень непустого дерева общего вида. Вывести указатель P2 на последнюю вершину дерева с наибольшей суммой значений дочерних вершин. Вершины перебирать в постфиксном порядке (см. задание Tree93).

Tree97. Дан указатель P1 на корень непустого дерева общего вида. В каждом наборе вершин-сестер заменить все значения вершин (т. е. значения полей Data) на максимальное из их исходных значений.

Tree98. Дан указатель P1 на корень непустого дерева общего вида. В каждом наборе вершин-сестер изменить порядок следования их значений на противоположный, т. е. поменять местами значения поля Data первой (левой) и последней (правой) сестры, второй и предпоследней сестры, и т. д.

Tree99. Дана строка S, содержащая описание непустого дерева общего вида в следующем формате:

<дерево> | ::= | <вершина> |
 |  | <вершина>(<список поддеревьев>)
<список поддеревьев> | ::= | <дерево> |
 |  | <дерево>,<список поддеревьев>
<вершина> | ::= | <цифра>

Например, «3(2,7(6,4,5),8(4(2,3),5(1)))» (пробелы отсутствуют, вершины-сестры перечисляются в порядке слева направо). Создать дерево общего вида по описанию, приведенному в S, и вывести указатель на его корень.

Tree100. Дан указатель P1 на корень непустого дерева общего вида. Вывести строку с описанием исходного дерева в формате, приведенном в задании Tree99.


Группы заданий

Деревья: группа Tree (.NET)

[Перейти к указаниям] [Перейти к началу раздела «Группы заданий»] [Перейти к началу раздела «Указания»]

В варианте задачника для системы PascalABC.NET группа имеет имя ObjTree. В веб-среде ProgrammingABC.NET WDE данная группа доступна для языков PascalABC.NET, C#, Visual Basic .NET под исходным именем Tree.

Все числа, используемые в заданиях на деревья, являются целыми. Все объекты имеют тип Node, который определен в задачнике Programming Taskbook. В заданиях на деревья у объектов типа Node используются свойства Data, Left, Right и Parent, поэтому при выполнении этих заданий можно считать, что класс Node включает следующие открытые свойства и методы:

[C#]

// Конструкторы:
public Node();
public Node(int aData);
public Node(Node aLeft, Node aRight, int aData);
public Node(Node aLeft, Node aRight, int aData, Node aParent);
// Свойства (доступны для чтения и для записи):
public int Data;
public Node Left;
public Node Right;
public Node Parent;
// Метод, освобождающий неуправляемые ресурсы, используемые объектом Node:
public void Dispose();

[VB.NET]

' Конструкторы:
Public Sub New()
Public Sub New(aData As Integer)
Public Sub New(aLeft As Node, aRight As Node, _
aData As Integer)
Public Sub New(aLeft As Node, aRight As Node, _
aData As Integer, aParent As Node)
' Свойства (доступны для чтения и для записи):
Public Property Data() As Integer
Public Property Left() As Node
Public Property Right() As Node
Public Property Parent() As Node
' Метод, освобождающий неуправляемые ресурсы, используемые объектом Node:
Public Sub Dispose() Implements IDisposable.Dispose

[PascalABC.NET]

// Конструкторы:
constructor Create;
constructor Create(aData: integer);
constructor Create(aLeft, aRight: Node; aData: integer);
constructor Create(aLeft, aRight: Node; aData: integer; aParent: Node);
// Свойства (доступны для чтения и для записи):
property Data: integer;
property Left: Node;
property Right: Node;
property Parent: Node;
// Метод, освобождающий неуправляемые ресурсы, используемые объектом:
procedure Dispose;

В большинстве заданий при работе с объектами типа Node требуются только свойства Data, Left и Right; свойство Parent используется лишь в заданиях на обработку дереьев с обратной связью.

Значением вершины дерева (т. е. объекта типа Node) считается значение ее свойства Data.

Так как в языках платформы .NET принята ссылочная объектная модель, т. е. любая переменная объектного типа является ссылкой на ту область памяти, в которой фактически размещен данный объект, выражение «вывести ссылку на вершину дерева» в формулировках заданий всегда означает, что требуется вывести значение переменной типа Node, связанной с этой вершиной.

Анализ бинарного дерева

Tree1. Дан объект A1 типа Node, имеющий открытые свойства Data (целого типа), Left и Right (типа Node). Свойства Left и Right этого объекта (корня дерева) содержат ссылки на левую и правую дочерние вершины (того же типа Node). Вывести значения свойств Data корня, его левой и правой дочерних вершин, а также ссылки на левую и правую дочерние вершины в указанном порядке.

Tree2. Дан объект A1 типа Node — корень дерева. Эта объект связан свойствами Left и Right с другими объектами того же типа (дочерними вершинами), они, в свою очередь, — со своими дочерними вершинами, и так далее до объектов, свойства Left и Right которых равны null (у некоторых вершин может быть равно null одно из свойств — Left или Right). Вывести количество вершин дерева.

Tree3. Дан корень A1 непустого дерева и число K. Вывести количество вершин дерева, значение которых равно K.

Tree4. Дан корень A1 непустого дерева. Вывести сумму значений всех вершин данного дерева.

Tree5. Дан корень A1 непустого дерева. Вывести количество вершин дерева, являющихся левыми дочерними вершинами (корень дерева не учитывать).

Tree6. Дан корень A1 непустого дерева. Листом дерева называется его вершина, не имеющая дочерних вершин. Вывести количество листьев для данного дерева.

Tree7. Дан корень A1 непустого дерева. Вывести сумму значений всех листьев данного дерева.

Tree8. Дан корень A1 дерева, содержащего по крайней мере две вершины. Вывести количество листьев дерева, являющихся правыми дочерними вершинами.

Tree9. Дан корень A1 непустого дерева. Считается, что корень дерева находится на нулевом уровне, его дочерние вершины — на первом уровне и т. д. Вывести глубину дерева, т. е. значение его максимального уровня (например, глубина дерева, состоящего только из корня, равна 0).

Tree10. Дан корень A1 непустого дерева. Для каждого из уровней данного дерева, начиная с нулевого, вывести количество вершин, находящихся на этом уровне. Считать, что глубина дерева не превосходит 10.

Tree11. Дан корень A1 непустого дерева. Для каждого из уровней данного дерева, начиная с нулевого, вывести сумму значений вершин, находящихся на этом уровне. Считать, что глубина дерева не превосходит 10.

Tree12. Дан корень A1 непустого дерева. Вывести значения всех вершин дерева в инфиксном порядке (вначале выводится содержимое левого поддерева в инфиксном порядке, затем выводится значение корня, затем — содержимое правого поддерева в инфиксном порядке).

Tree13. Дан корень A1 непустого дерева. Вывести значения всех вершин дерева в префиксном порядке (вначале выводится значение корня, затем содержимое левого поддерева в префиксном порядке, затем — содержимое правого поддерева в префиксном порядке).

Tree14. Дан корень A1 непустого дерева. Вывести значения всех вершин дерева в постфиксном порядке (вначале выводится содержимое левого поддерева в постфиксном порядке, затем — содержимое правого поддерева в постфиксном порядке, затем — значение корня).

Tree15. Дан корень A1 непустого дерева и число N (> 0), не превосходящее количество вершин в исходном дереве. Нумеруя вершины в инфиксном порядке (см. задание Tree12, нумерация ведется от 1), вывести значения всех вершин с порядковыми номерами от 1 до N.

Tree16. Дан корень A1 непустого дерева и число N (> 0), не превосходящее количество вершин в исходном дереве. Нумеруя вершины в постфиксном порядке (см. задание Tree14, нумерация ведется от 1), вывести значения всех вершин с порядковыми номерами от N до максимального номера.

Tree17. Дан корень A1 непустого дерева и два числа N1, N2 (0 < N1 < N2), которые не превосходят количество вершин в исходном дереве. Нумеруя вершины в префиксном порядке (см. задание Tree13, нумерация ведется от 1), вывести значения всех вершин с порядковыми номерами от N1 до N2.

Tree18. Дан корень A1 непустого дерева и неотрицательное число L. Используя любой из описанных в заданиях Tree12−Tree14 способов обхода дерева, вывести значения всех вершин уровня L, а также их количество N (если дерево не содержит вершин уровня L, то вывести 0).

Tree19. Дан корень A1 непустого дерева. Вывести максимальное из значений его вершин и количество вершин, имеющих это максимальное значение.

Tree20. Дан корень A1 непустого дерева. Вывести минимальное из значений всех его вершин и количество листьев, имеющих это минимальное значение (данное количество может быть равно 0).

Tree21. Дан корень A1 непустого дерева. Вывести минимальное из значений его вершин, являющихся листьями.

Tree22. Дан корень A1 дерева, содержащего по крайней мере две вершины. Вывести максимальное из значений его внутренних вершин (т. е. вершин, не являющихся листьями).

Tree23. Дан корень A1 непустого дерева. Вывести ссылку A2 на первую вершину дерева с минимальным значением (вершины перебирать в префиксном порядке).

Tree24. Дан корень A1 непустого дерева. Вывести ссылку A2 на последнюю вершину дерева с максимальным нечетным значением (вершины перебирать в инфиксном порядке). Если дерево не содержит вершин с нечетными значениями, то вывести null.

Формирование бинарного дерева

Tree25. Дано число N (> 0) и набор из N чисел. Создать дерево из N вершин, в котором каждая вершина (кроме корня) является правой дочерней вершиной. Каждой создаваемой вершине присваивать очередное значение из исходного набора. Вывести ссылку на корень созданного дерева.

Tree26. Дано число N (> 0) и набор из N чисел. Создать дерево из N вершин, в котором каждая внутренняя вершина имеет только одну дочернюю вершину, причем правые и левые дочерние вершины чередуются (корень имеет левую дочернюю вершину). Каждой создаваемой вершине присваивать очередное значение из исходного набора. Вывести ссылку на корень созданного дерева.

Tree27. Дано число N (> 0) и набор из N чисел. Создать дерево из N вершин, в котором каждая внутренняя вершина имеет только одну дочернюю вершину, причем если значение вершины является нечетным, то она имеет левую дочернюю вершину, а если четным, то правую. Каждой создаваемой вершине присваивать очередное значение из исходного набора. Вывести ссылку на корень созданного дерева.

Tree28. Дано четное число N (> 0) и набор из N чисел. Создать дерево из N вершин, в котором каждая левая дочерняя вершина является листом, а правая дочерняя вершина является внутренней. Для каждой внутренней вершины вначале создавать левую дочернюю вершину, а затем правую (если она существует); каждой создаваемой вершине присваивать очередное значение из исходного набора. Вывести ссылку на корень созданного дерева.

Tree29. Дано четное число N (> 0) и набор из N чисел. Создать дерево из N вершин со следующей структурой: если вершина дерева является внутренней, то в случае, если она имеет нечетное значение, ее левая дочерняя вершина должна быть листом, а в случае, если она имеет четное значение, листом должна быть ее правая вершина. Для каждой внутренней вершины вначале создавать дочернюю вершину-лист, а затем дочернюю внутреннюю вершину (если данная вершина существует); каждой создаваемой вершине присваивать очередное значение из исходного набора. Вывести ссылку на корень созданного дерева.

Tree30. Дано число N (> 0). Создать дерево, корень которого имеет значение N, а вершины обладают следующими свойствами: вершина с четным значением K имеет левую дочернюю вершину со значением K/2 и не имеет правой дочерней вершины; вершина со значением 1 является листом; вершина с любым другим нечетным значением K имеет две дочерние вершины: левую со значением K/2 и правую со значением K − K/2 (символ «/» обозначает операцию деления нацело). Вывести ссылку на корень созданного дерева.

Tree31. Даны положительные числа L, N (N > L) и набор из N чисел. Создать дерево глубины L, содержащее вершины со значениями из исходного набора. Вершины добавлять к дереву в префиксном порядке, используя алгоритм, который для каждой вершины уровня, не превышающего L, вначале создает саму вершину с очередным значением из исходного набора, затем ее левое поддерево соответствующей глубины, а затем ее правое поддерево. Если для заполнения дерева глубины L требуется менее N вершин, то оставшиеся числа из исходного набора не использовать. Вывести ссылку на корень созданного дерева.

Tree32. Дано число N (> 0) и набор из N чисел. Создать идеально сбалансированное дерево из N вершин с заданными значениями (т. е. дерево, для каждой вершины которого количество вершин в его левом и правом поддереве отличается не более чем на 1) и вывести ссылку на его корень. Для создания дерева использовать рекурсивный алгоритм, который создает вершину дерева с очередным значением, после чего вызывается для создания левого поддерева с N/2 вершинами и правого поддерева с N − 1 − N/2 вершинами (символ «/» обозначает операцию деления нацело).

Tree33. Дано число N (> 0). Создать идеально сбалансированное дерево из N вершин и вывести ссылку на его корень. Значение каждой вершины положить равным уровню этой вершины (например, корень дерева должен иметь значение 0, его дочерние вершины — значение 1 и т. д.). При формировании дерева использовать алгоритм, описанный в задании Tree32.

Tree34. Дан корень A1 непустого дерева. Создать копию данного дерева и вывести ссылку A2 на корень созданной копии.

Преобразование бинарного дерева

Tree35. Дан корень A1 непустого дерева. Удвоить значение каждой вершины дерева.

Tree36. Дан корень A1 непустого дерева. Для каждой вершины дерева с четным значением уменьшить ее значение в два раза.

Tree37. Дан корень A1 непустого дерева. Добавить 1 к значению каждого листа дерева и вычесть 1 из значения каждой внутренней вершины.

Tree38. Дан корень A1 непустого дерева. Для каждой вершины дерева, имеющей две дочерние вершины, поменять местами значения дочерних вершин (т. е. значения их свойств Data).

Tree39. Дан корень A1 непустого дерева. Для всех внутренних вершин дерева поменять местами их левые и правые дочерние вершины (т. е. значения свойств Left и Right).

Tree40. Дан корень A1 непустого дерева. Удалить из дерева все вершины, кроме корня (свойствам Left и Right корня следует присвоить значение null). После удаления вершин освобождать ресурсы, которые они использовали, вызывая для этих вершин метод Dispose.

Tree41. Дан корень A1 дерева, содержащего по крайней мере две вершины. Удалить каждую вершину дерева, являющуюся листом; при этом соответствующее свойство родительской вершины (Left или Right) следует положить равным null. После удаления вершин из дерева вызывать для них метод Dispose.

Tree42. Дан корень A1 непустого дерева. Удалить вершины дерева, имеющие значения, меньшие значения корня, вместе со всеми их дочерними вершинами. После удаления вершин из дерева вызывать для них метод Dispose.

Tree43. Дан корень A1 непустого дерева. Для вершин дерева, имеющих две дочерние вершины, удалить одну из дочерних вершин: правую, если родительская вершина имеет четное значение, и левую в противном случае (вершины дерева перебирать в префиксном порядке, при удалении вершины удалять и всех ее потомков). Для удаленных вершин вызывать метод Dispose.

Tree44. Дан корень A1 непустого дерева. Ко всем вершинам дерева, которые являются листьями, добавить по две дочерние вершины-листа: левую со значением 10 и правую со значением 11.

Tree45. Дан корень A1 непустого дерева. Ко всем вершинам дерева, которые являются листьями, добавить по одной дочерней вершине-листу; при этом к исходной вершине с нечетным значением добавляется левая дочерняя вершина, а к вершине с четным значением — правая. Значение каждой добавленной вершины положить равным значению ее родительской вершины.

Tree46. Дан корень A1 непустого дерева. Ко всем вершинам дерева, которые содержат ровно по одной дочерней вершине, добавить еще одину дочернюю вершину-лист. Значение каждой добавленной вершины положить равным удвоенному значению ее родительской вершины.

Tree47. Дан корень A1 непустого дерева. Не изменяя глубины L исходного дерева, дополнить его до полного дерева, т. е. дерева, все листья которого находятся на уровне L. Значения всех добавленных вершин положить равными −1.

Бинарные деревья с обратной связью

Tree48. Дана вершина дерева A1 — объект типа Node, имеющий открытые свойства Data (целого типа), Left, Right и Parent (типа Node). Свойства Left и Right содержат ссылки на дочерние вершины, а свойство Parent — на родительскую вершину данной вершины (если вершина является корнем дерева, то ее свойство Parent равно null). Для данной вершины вывести ссылки AL, AR и A0 на ее левую и правую дочерние вершины и родительскую вершину, а также ссылку A2 на ее сестру, т. е. другую вершину дерева, имеющую в качестве родительской вершину A0. Если некоторые из перечисленных вершин не существуют, то вывести для них значение null.

Tree49. Дан корень A1 дерева, вершинами которого являются объекты типа Node, связанные между собой с помощью свойств Left и Right. Используя свойство Parent объекта Node, преобразовать исходное дерево в дерево с обратной связью, в котором каждая вершина связана не только со своими дочерними вершинами (свойствами Left и Right), но и с родительской вершиной (свойством Parent). Свойство Parent корня дерева положить равным null.

Tree50. Дана ссылка A1 на одну из вершин дерева с обратной связью. Вывести ссылку A2 на корень исходного дерева.

Tree51. Даны ссылки A1, A2, A3 на три вершины дерева с обратной связью. Для каждой из данных вершин вывести ее уровень (корень дерева имеет уровень 0).

Tree52. Даны ссылки A1 и A2 на две различные вершины дерева с обратной связью. Вывести степень родства вершины A1 по отношению к вершине A2 (степень родства равна −1, если вершина A2 не находится в цепочке предков для вершины A1; в противном случае степень родства равна L1 − L2, где L1 и L2 — уровни вершин A1 и A2 соответственно).

Tree53. Даны ссылки A1 и A2 на две различные вершины дерева с обратной связью. Вывести ссылку A0 на вершину дерева, являющуюся ближайшим общим предком вершин A1 и A2.

Tree54. Дана ссылка A1 на одну из вершин дерева с обратной связью. Создать копию данного дерева и вывести ссылку A2 на корень созданной копии.

Tree55. Дана ссылка A1 на вершину дерева с обратной связью, которая не является корнем. Если вершина A1 имеет сестру, то удалить эту сестру вместе со всеми ее потомками (и вызвать для них метод Dispose); если вершина A1 не имеет сестры, то создать сестру и всех ее потомков в виде копии поддерева с корнем A1. Вывести ссылку A0 на родительскую вершину вершины A1.

Tree56. Даны положительные числа L, N (N > L) и набор из N чисел. Сформировать дерево глубины L с обратной связью, содержащее вершины со значениями из исходного набора. Вершины добавлять к дереву в префиксном порядке, используя алгоритм, который для каждой вершины уровня, не превышающего L, вначале создает саму вершину с очередным значением из исходного набора, затем ее левое поддерево соответствующей глубины, а затем ее правое поддерево. Если для заполнения дерева глубины L требуется менее N вершин, то оставшиеся числа из исходного набора не использовать. Вывести ссылку на корень созданного дерева.

Бинарные деревья поиска

Tree57. Дан корень A1 непустого дерева. Если данное дерево является деревом поиска, т. е. если при обходе его вершин в инфиксном порядке их значения образуют неубывающую последовательность, то вывести null; в противном случае вывести адрес первой вершины (в инфиксном порядке), нарушающей требуемую закономерность.

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

Tree59. Дан корень A1 непустого дерева поиска без повторяющихся элементов и число K. Определить, содержит ли исходное дерево вершину со значением K. Если содержит, то вывести ссылку A2 на эту вершину, в противном случае вывести null. Вывести также количество N вершин, которые потребовалось проанализировать для выполнения задания.

Tree60. Дан корень A1 непустого дерева поиска и число K. Вывести количество C вершин исходного дерева, имеющих значение K, а также количество N вершин, которые потребовалось проанализировать для выполнения задания.

Tree61. Дан корень A1 дерева поиска (если дерево является пустым, то A1 = null). Также дано число K. Добавить к исходному дереву поиска новую вершину со значением K таким образом, чтобы полученное дерево осталось деревом поиска, и вывести ссылку A2 на корень полученного дерева. Использовать следующий рекурсивный алгоритм для дерева с корнем A: если A = null, то создать лист со значением K и присвоить объекту A ссылку на созданный лист; если корень A существует, то в случае, если его значение больше K, выполнить алгоритм для свойства Left корня A, иначе выполнить алгоритм для его свойства Right.

Tree62. Дан корень A1 дерева поиска без повторяющихся элементов (если дерево является пустым, то A1 = null). Также дано число K. Добавить к исходному дереву поиска новую вершину со значением K таким образом, чтобы полученное дерево осталось деревом поиска без повторяющихся элементов, и вывести ссылку A2 на корень полученного дерева. Если исходное дерево уже содержит вершину со значением K, то оставить дерево без изменений. Использовать следующий рекурсивный алгоритм для дерева с корнем A: если A = null, то создать лист со значением K и присвоить объекту A ссылку на созданный лист; если корень A существует, то в случае, если его значение больше K, выполнить алгоритм для свойства Left корня A, а в случае, если его значение меньше K, выполнить алгоритм для его свойства Right.

Tree63. Дано число N (> 0) и набор из N чисел, а также корень A1 дерева поиска (если дерево является пустым, то A1 = null). Добавить к исходному дереву поиска N новых вершин со значениями из исходного набора таким образом, чтобы полученное дерево осталось деревом поиска, и вывести ссылку A2 на корень полученного дерева. Для добавления новых вершин использовать алгоритм, описанный в задании Tree61.

Tree64. Дано число N (> 0) и набор из N чисел, а также корень A1 дерева поиска без повторяющихся элементов (если дерево является пустым, то A1 = null). Добавить к исходному дереву поиска новые вершины со значениями из исходного набора таким образом, чтобы полученное дерево осталось деревом поиска без повторяющихся элементов, и вывести ссылку A2 на корень полученного дерева. Для добавления новых вершин использовать алгоритм, описанный в задании Tree62.

Tree65. Дано число N (> 0) и набор из N чисел. Отсортировать исходный набор чисел, создав для него дерево поиска (алгоритм добавления вершин к дереву поиска описан в задании Tree61). Вывести ссылку A1 на корень полученного дерева, а также отсортированный набор чисел (для вывода набора чисел выполнить перебор вершин дерева в инфиксном порядке).

Tree66. Дано число N (> 0) и набор из N чисел. Получить отсортированный набор исходных чисел без повторений, создав для исходного набора дерево поиска без повторяющихся элементов (алгоритм добавления вершин к подобному дереву описан в задании Tree62). Вывести ссылку A1 на корень полученного дерева, а также отсортированный набор чисел без повторений (для вывода набора чисел выполнить перебор вершин дерева в инфиксном порядке).

Tree67. Даны две ссылки: A1 на корень непустого дерева поиска и A2 на одну из вершин этого дерева, имеющих не более одной дочерней вершины. Удалить из исходного дерева вершину A2 так, чтобы полученное дерево осталось деревом поиска (если удаляемая вершина A2 имеет дочернюю вершину, то эту дочернюю вершину необходимо связать с родительской вершиной вершины A2). Вывести ссылку A3 на корень полученного дерева или null, если в результате удаления вершины A2 дерево стало пустым.

Tree68. Даны два ссылки: A1 на корень непустого дерева поиска и A2 на одну из вершин этого дерева, имеющих две дочерние вершины. Удалить из исходного дерева вершину A2 так, чтобы полученное дерево осталось деревом поиска. Удаление выполнять следующим образом: в левом поддереве вершины A2 найти вершину A с наибольшим значением, присвоить это наибольшее значение вершине A2, после чего удалить вершину A, действуя, как в задании Tree67 (поскольку вершина A будет иметь не более одной дочерней вершины).

Tree69. Даны два ссылки: A1 на корень непустого дерева поиска и A2 на одну из вершин этого дерева, имеющих две дочерние вершины. Удалить из исходного дерева вершину A2 так, чтобы полученное дерево осталось деревом поиска. Удаление выполнять следующим образом: в правом поддереве вершины A2 найти вершину A с наименьшим значением, присвоить это наименьшее значение вершине A2, после чего удалить вершину A, действуя, как в задании Tree67 (поскольку вершина A будет иметь не более одной дочерней вершины).

Tree70. Дана ссылка A1 на одну из вершин непустого дерева поиска с обратной связью. Удалить из исходного дерева вершину A1 таким образом, чтобы полученное дерево осталось деревом поиска с обратной связью, и вывести ссылку A2 на корень полученного дерева или null, если в результате удаления дерево стало пустым. Если вершина A1 имеет две дочерние вершины, то для ее удаления использовать алгоритм, описанный в задании Tree68.

Tree71. Дана ссылка A1 на одну из вершин непустого дерева поиска с обратной связью. Удалить из исходного дерева вершину A1 таким образом, чтобы полученное дерево осталось деревом поиска с обратной связью, и вывести ссылку A2 на корень полученного дерева или null, если в результате удаления дерево стало пустым. Если вершина A1 имеет две дочерние вершины, то для ее удаления использовать алгоритм, описанный в задании Tree69.

Бинарные деревья разбора выражений

Tree72. Дана строка S, содержащая описание непустого дерева в следующем формате:

<дерево> | ::= | <пусто> |
 |  | <вершина>(<левое поддерево>,<правое поддерево>)
<вершина> | ::= | <цифра>

Например, «4(2(,),6(,7(3(,),)))» (пробелы отсутствуют). Создать дерево по описанию, приведенному в S, и вывести ссылку на его корень.

Tree73. Дан корень A1 непустого дерева. Вывести строку с описанием исходного дерева в формате, приведенном в задании Tree72.

Tree74. Дана строка S, содержащая описание непустого дерева в следующем формате:

<дерево> | ::= | <вершина> |
 |  | <вершина>(<левое поддерево>,<правое поддерево>) |
 |  | <вершина>(<левое поддерево>) |
 |  | <вершина>(,<правое поддерево>)
<вершина> | ::= | <цифра>

Например, «4(2,6(,7(3)))» (пробелы отсутствуют, вид описания вершины зависит от того, имеет ли вершина непустое левое и/или правое поддерево). Создать дерево по описанию, приведенному в S, и вывести ссылку на его корень.

Tree75. Дан корень A1 непустого дерева. Вывести строку с описанием исходного дерева в формате, приведенном в задании Tree74.

Tree76. Дана строка S, содержащая описание числового выражения в следующем формате:

<выражение> | ::= | <цифра> |
 |  | (<выражение><знак><выражение>)
<знак> | ::= | + | − | *

Пробелы в строке отсутствуют. Создать дерево, соответствующее исходному выражению (дерево разбора выражения): каждая внутренняя вершина дерева должна соответствовать одной из трех возможных арифметических операций и иметь значение −1 для операции сложения, −2 для операции вычитания и −3 для операции умножения; левое и правое дочерние поддеревья любой внутренней вершины-операции должны соответствовать выражениям слева и справа от знака операции; листьями полученного дерева должны быть выражения-цифры. Вывести ссылку на корень созданного дерева.

Tree77. Дана строка S, содержащая описание числового выражения в следующем формате (так называемый префиксный бесскобочный формат записи числового выражения):

<выражение> | ::= | <цифра> |
 |  | <знак> <выражение> <выражение>
<знак> | ::= | + | − | *

Выражения отделяются друг от друга и от знаков операций ровно одним пробелом. Создать дерево разбора выражения и вывести ссылку на его корень. Структура дерева разбора выражения описана в задании Tree76; для каждой вершины-операции ее левое поддерево должно соответствовать первому операнду данной операции, а правое поддерево — второму.

Tree78. Дана строка S, содержащая описание числового выражения в следующем формате (так называемый постфиксный бесскобочный формат записи числового выражения):

<выражение> | ::= | <цифра> |
 |  | <выражение> <выражение> <знак>
<знак> | ::= | + | − | *

Выражения отделяются друг от друга и от знаков операций ровно одним пробелом. Создать дерево разбора выражения и вывести ссылку на его корень. Структура дерева разбора выражения описана в задании Tree76; для каждой вершины-операции ее левое поддерево должно соответствовать первому операнду данной операции, а правое поддерево — второму.

Tree79. Дан корень A1 непустого дерева разбора выражения (структура дерева описана в задании Tree76). Вывести значение выражения, определяемого исходным деревом.

Tree80. Дан корень A1 непустого дерева разбора выражения (структура дерева описана в задании Tree76). Вывести строковое представление соответствующего выражения в формате, приведенном в том же задании:

<выражение> | ::= | <цифра> |
 |  | (<выражение><знак><выражение>)
<знак> | ::= | + | − | *

Tree81. Дан корень A1 непустого дерева разбора выражения. Вывести строковое представление соответствующего выражения в префиксном бесскобочном формате (см. задание Tree77).

Tree82. Дан корень A1 непустого дерева разбора выражения. Вывести строковое представление соответствующего выражения в постфиксном бесскобочном формате (см. задание Tree78).

Tree83. Дана строка S, содержащая описание числового выражения в следующем формате (функция M возвращает максимальное из двух выражений, а m — минимальное):

<выражение> | ::= | <цифра> | M(<выражение> , <выражение>) |
 |  | m(<выражение> , <выражение>)

Пробелы в строке отсутствуют. Создать дерево разбора исходного выражения: каждая внутренняя вершина дерева должна соответствовать одной из двух возможных функций и иметь значение −1 для функции M и −2 для функции m; для каждой вершины-функции ее левое поддерево должно соответствовать первому аргументу функции, а правое поддерево — второму; листьями полученного дерева должны быть выражения-цифры. Вывести ссылку на корень созданного дерева.

Tree84. Дан корень A1 непустого дерева разбора выражения (структура дерева описана в задании Tree83). Вывести значение выражения, определяемого исходным деревом.

Tree85. Дан корень A1 непустого дерева разбора выражения (структура дерева описана в задании Tree83). Вывести строковое представление соответствующего выражения в формате, приведенном в том же задании:

<выражение> | ::= | <цифра> | M(<выражение> , <выражение>) |
 |  | m(<выражение> , <выражение>)

Деревья общего вида

Tree86. Дерево общего вида (каждая вершина которого может иметь произвольное число дочерних вершин, расположенных в фиксированном порядке в направлении слева направо) реализуется с помощью набора связанных объектов типа Node следующим образом: для каждой внутренней вершины ее свойство Left содержит ссылку на ее первую (т. е. левую) дочернюю вершину, а свойство Right — ссылку на ее правую сестру, т. е. вершину, имеющую в дереве общего вида того же родителя. Свойство Right корня дерева общего вида всегда равно null, так как корень сестер не имеет. Дан корень A1 непустого бинарного дерева. Создать дерево общего вида, соответствующее исходному бинарному дереву, и вывести ссылку A2 на его корень.

Tree87. Дан корень A1 непустого дерева общего вида. Любая вершина исходного дерева имеет не более двух дочерних вершин. Создать бинарное дерево, соответствующее исходному дереву общего вида, и вывести ссылку A2 на его корень. Считать, что первая дочерняя вершина любой вершины дерева общего вида соответствует левой дочерней вершине в бинарном дереве.

Tree88. Дан корень A1 непустого дерева общего вида. Вывести глубину данного дерева, т. е. значение его максимального уровня, считая, что все вершины-сестры находятся на одном уровне, а корень дерева расположен на уровне 0.

Tree89. Дан корень A1 непустого дерева общего вида. Для каждого из уровней данного дерева, начиная с уровня 0, вывести количество вершин, находящихся на этом уровне. Считать, что глубина исходного дерева общего вида не превосходит 10.

Tree90. Дан корень A1 непустого дерева общего вида. Для каждого из уровней данного дерева, начиная с уровня 0, вывести сумму значений вершин, находящихся на этом уровне. Считать, что глубина исходного дерева общего вида не превосходит 10.

Tree91. Дан корень A1 непустого дерева общего вида. Также дано неотрицательное число L. Перебирая дочерние вершины в заданном порядке (т. е. слева направо), вывести значения всех вершин уровня L и их количество N. Если дерево не содержит вершин уровня L, то вывести 0.

Tree92. Дан корень A1 непустого дерева общего вида. Вывести значения всех вершин дерева в инфиксном порядке: вначале выводится содержимое первого (левого) поддерева в инфиксном порядке, затем выводится значение корня, а затем — содержимое остальных поддеревьев в инфиксном порядке (поддеревья перебираются слева направо).

Tree93. Дан корень A1 непустого дерева общего вида. Вывести значения всех вершин дерева в постфиксном порядке: вначале выводится содержимое каждого поддерева в постфиксном порядке (поддеревья перебираются слева направо), а затем — значение корня.

Tree94. Дан корень A1 непустого дерева общего вида. Также дано неотрицательное число N. Вывести количество вершин исходного дерева, имеющих ровно N дочерних вершин. Если требуемые вершины отсутствуют, то вывести 0.

Tree95. Дан корень A1 непустого дерева общего вида. Вывести ссылку A2 на первую вершину дерева, имеющую наибольшее количество дочерних вершин. Вершины перебирать в инфиксном порядке (см. задание Tree92).

Tree96. Дан корень A1 непустого дерева общего вида. Вывести ссылку A2 на последнюю вершину дерева с наибольшей суммой значений дочерних вершин. Вершины перебирать в постфиксном порядке (см. задание Tree93).

Tree97. Дан корень A1 непустого дерева общего вида. В каждом наборе вершин-сестер заменить все значения вершин (т. е. значения свойств Data) на максимальное из их исходных значений.

Tree98. Дан корень A1 непустого дерева общего вида. В каждом наборе вершин-сестер изменить порядок следования их значений на противоположный, т. е. поменять местами значения свойства Data первой (левой) и последней (правой) сестры, второй и предпоследней сестры, и т. д.

Tree99. Дана строка S, содержащая описание непустого дерева общего вида в следующем формате:

<дерево> | ::= | <вершина> |
 |  | <вершина>(<список поддеревьев>)
<список поддеревьев> | ::= | <дерево> |
 |  | <дерево>,<список поддеревьев>
<вершина> | ::= | <цифра>

Например, «3(2,7(6,4,5),8(4(2,3),5(1)))» (пробелы отсутствуют, вершины-сестры перечисляются в порядке слева направо). Создать дерево общего вида по описанию, приведенному в S, и вывести ссылку на его корень.


Группы заданий

ЕГЭ по информатике, базовые алгоритмы: группа ExamBegin

Данная группа включает все виды алгоритмических задач, перечисленные в кодификаторе ЕГЭ по информатике и ИКТ.

При выполнении заданий данной группы вместо специальных операций ввода-вывода, предоставляемых задачником, необходимо применять стандартные операции используемого языка программирования: процедуры Read/Readln–Write/Writeln для языка Pascal и потоки cin–cout для языка C++.

Если числа содержат дробную часть, то она отделяется от целой части десятичной точкой.

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

При выводе вещественных чисел следует указывать два дробных знака. Если в задании сказано, сколько экранных позиций надо отводить для вывода чисел, то всегда считается, что дополнительные пробелы добавляются слева (т. е. что числа выравниваются по правой границе области вывода).

Двумерный числовой массив размера M × N всегда интерпретируется как прямоугольная таблица чисел, содержащая M строк и N столбцов; при этом первый индекс элемента массива определяет строку, в которой находится элемент, а второй — столбец. Элементы исходного двумерного массива вводятся по строкам; каждая экранная строка содержит элементы одной строки массива. Во всех заданиях, связанных с массивами, предполагается, что размер одномерного массива не превосходит 100 элементов, а число строк и столбцов двумерного массива не превосходит 10.

Условные операторы и циклы

ExamBegin1. На вход подаются два целых числа; числа расположены в одной строке. Вывести вначале максимальное, а затем минимальное из них. Числа должны выводиться в одной строке и разделяться одним пробелом.

ExamBegin2. На вход подаются три вещественных числа; числа расположены в одной строке. Вывести вначале минимальное, а затем максимальное из них. Каждое число должно выводиться на новой строке и снабжаться комментарием: «MIN=» для минимального, «MAX=» для максимального.

ExamBegin3. На вход подаются четыре целых числа; каждое число вводится с новой строки. Вывести минимальное из них.

ExamBegin4. На вход подаются три целых числа — коэффициенты A, B, C квадратного уравнения A·x2 + B·x + C = 0 (A не равно 0). Каждое число вводится с новой строки. Найти корни данного уравнения. Корни вычисляются как вещественные числа. Если имеются два различных корня, то вначале выводить меньший, а затем больший (каждый на новой строке). Если корней нет, то вывести текст «NO».

ExamBegin5. На вход подаются два целых положительных числа; каждое число вводится с новой строки. Найти их наибольший общий делитель (НОД), используя алгоритм Евклида:

НОД(A, B) = НОД(B, A mod B), если B ≠ 0; НОД(A, 0) = A,

где «mod» обозначает операцию взятия остатка от деления.

ExamBegin6. На вход подаются два целых положительных числа; числа расположены в одной строке. Найти их наименьшее общее кратное (НОК), используя формулу

НОК(A, B) = A·(B/НОД(A, B)),

где НОД(A, B) — наибольший общий делитель, а символ «/» обозначает операцию деления нацело. НОД находить с помощью алгоритма Евклида (см. задание ExamBegin5).

ExamBegin7. На вход подаются два целых положительных числа: A и D (2 ≤ D ≤ 9); числа расположены в одной строке. Вывести строку, изображающую запись числа A в системе счисления с основанием D (полученная строка не должна содержать незначащих нулей).

ExamBegin8. На вход в первой строке подается целое число D (2 ≤ D ≤ 9), а во второй строке — текст, изображающий запись целого положительного числа A в системе счисления с основанием D. Вывести число A в десятичной системе счисления.

ExamBegin9. На вход подается целое положительное число. Если оно является степенью числа 2, то вывести текст «YES», иначе вывести «NO».

ExamBegin10. На вход подаются два целых положительных числа A и K; каждое число располагается на новой строке. Если число A является степенью числа K, т. е. A = KN, то вывести показатель этой степени N, иначе вывести текст «NO».

ExamBegin11. На вход подается целое число, большее 1. Вывести наименьший делитель данного числа, больший 1.

ExamBegin12. На вход подается целое число, большее 1. Если оно является простым, т. е. не имеет положительных делителей, кроме 1 и самого себя, то вывести текст «YES», иначе вывести «NO».

ExamBegin13. На вход подается целое число, большее 1. Разложить данное число на простые множители и вывести все множители в порядке возрастания (каждое число выводить на новой строке, среди выводимых чисел могут быть одинаковые).

ExamBegin14. На вход в первой строке подается целое положительное число N, а во второй строке — набор из N целых чисел. Вывести сумму всех чисел из исходного набора.

ExamBegin15. На вход в первой строке подается целое положительное число N, а в следующих N строках — набор из N вещественных чисел (по одному числу в строке). Вывести произведение всех чисел из исходного набора.

ExamBegin16. На вход подается набор целых чисел, содержащий одно или более ненулевых чисел и завершающийся числом 0; каждое число располагается на новой строке. Вывести сумму всех чисел из исходного набора.

ExamBegin17. На вход подается набор вещественных чисел, содержащий одно или более положительных чисел и завершающийся отрицательным числом; все числа расположены в одной строке. Вывести произведение всех положительных чисел из исходного набора.

Формирование массивов

ExamBegin18. На вход подается целое положительное число N. Сформировать и вывести целочисленный массив размера N, содержащий N первых положительных нечетных чисел: 1, 3, 5, … . Каждое число выводить на новой строке.

ExamBegin19. На вход подается целое положительное число N. Сформировать и вывести целочисленный массив размера N, содержащий степени двойки от первой до N-й: 2, 4, 8, 16, … . Выводить все числа в одной строке, для каждого числа отводить 5 экранных позиций.

ExamBegin20. На вход подаются три числа: целое число N (> 1) и вещественные числа A и D — соответственно первый член и разность арифметической прогрессии (каждое число вводится с новой строки). Сформировать и вывести массив размера N, содержащий N первых членов данной прогрессии: A, A + D, A + 2·D, A + 3·D, … . Все числа выводить в одной строке, для каждого числа отводить 7 экранных позиций.

ExamBegin21. На вход подаются три числа: целое число N (> 1) и вещественные числа A и D — соответственно первый член и разность геометрической прогрессии (все числа расположены в одной строке). Сформировать и вывести массив размера N, содержащий N первых членов данной прогрессии: A, A·D, A·D2, A·D3, … . Каждое число выводить на новой строке.

ExamBegin22. На вход подается целое число N (> 2). Сформировать и вывести целочисленный массив размера N, содержащий N первых элементов последовательности чисел Фибоначчи FK:

F1 = 1, F2 = 1, FK = FK−2 + FK−1, K = 3, 4, … .

Все числа выводить в одной строке, для каждого числа отводить 4 экранные позиции.

ExamBegin23. На вход подаются три целых числа: N (> 2), A и B (все числа расположены в одной строке). Сформировать и вывести целочисленный массив размера N, первый элемент которого равен A, второй равен B, а каждый последующий элемент равен сумме всех предыдущих. Каждое число выводить на новой строке.

ExamBegin24. На вход подаются два целых положительных числа M и N (каждое число вводится с новой строки). Сформировать и вывести двумерный целочисленный массив размера M × N, у которого все элементы I-й строки имеют значение 10·I (I = 1, …, M). Каждую строку элементов массива выводить на новой экранной строке, для каждого числа отводить 6 экранных позиций.

ExamBegin25. На вход подаются два целых положительных числа M и N (числа располагаются в одной строке). Сформировать и вывести двумерный целочисленный массив размера M × N, у которого все элементы J-го столбца имеют значение 5·J (J = 1, …, N). Каждую строку элементов массива выводить на новой экранной строке, для каждого числа отводить 6 экранных позиций.

ExamBegin26. На вход в первой строке подаются два целых положительных числа M и N, а во второй строке — набор из M вещественных чисел. Сформировать и вывести двумерный вещественный массив размера M × N, у которого в каждом столбце содержатся все числа из исходного набора (в том же порядке). Каждую строку элементов массива выводить на новой экранной строке, для каждого числа отводить 7 экранных позиций.

ExamBegin27. На вход в первой строке подаются два целых положительных числа M и N, а во второй строке — набор из N вещественных чисел. Сформировать и вывести двумерный вещественный массив размера M × N, у которого в каждой строке содержатся все числа из исходного набора (в том же порядке). Каждую строку элементов массива выводить на новой экранной строке, для каждого числа отводить 7 экранных позиций.

ExamBegin28. На вход в первой строке подаются два целых положительных числа M и N, во второй строке — вещественное число D, а в третьей строке — набор из M вещественных чисел. Сформировать и вывести двумерный вещественный массив размера M × N, у которого первый столбец совпадает с исходным набором чисел, а элементы каждого следующего столбца равны сумме соответствующего элемента предыдущего столбца и числа D (в результате каждая строка массива будет содержать элементы арифметической прогрессии). Каждую строку элементов массива выводить на новой экранной строке, для каждого числа отводить 7 экранных позиций.

ExamBegin29. На вход в первой строке подаются два целых положительных числа M и N и вещественное число D, а во второй строке — набор из N вещественных чисел. Сформировать и вывести двумерный вещественный массив размера M × N, у которого первая строка совпадает с исходным набором чисел, а элементы каждой следующей строки равны соответствующему элементу предыдущей строки, умноженному на D (в результате каждый столбец массива будет содержать элементы геометрической прогрессии). Каждую строку элементов массива выводить на новой экранной строке, для каждого числа отводить 8 экранных позиций.

Анализ одномерных массивов

ExamBegin30. На вход в первой строке подается целое число A, во второй строке — целое положительное число N, а в третьей строке — массив из N целых чисел. Определить, содержит ли массив элемент со значением A. Если содержит, то вывести текст «YES», если не содержит, то вывести «NO».

ExamBegin31. На вход в первой строке подается целое число A, во второй строке — целое положительное число N, а в третьей строке — массив из N целых чисел. Найти номер первого элемента массива со значением A (элементы нумеруются от 1). Если требуемые элементы в массиве отсутствуют, то вывести 0.

ExamBegin32. На вход в первой строке подается целое число A, во второй строке — целое положительное число N, а в третьей строке — массив из N целых чисел. Найти номер последнего элемента массива со значением A (элементы нумеруются от 1). Если требуемые элементы в массиве отсутствуют, то вывести 0.

ExamBegin33. На вход в первой строке подается целое положительное число N, а во второй строке — массив из N целых чисел. Определить, содержит ли массив четные числа. Если содержит, то вывести текст «YES», если не содержит, то вывести «NO».

ExamBegin34. На вход в первой строке подается целое положительное число N, а во второй строке — массив из N целых чисел. Найти количество нечетных чисел в массиве. Если нечетных чисел нет, то вывести 0.

ExamBegin35. На вход в первой строке подается целое положительное число N, а во второй строке — массив из N вещественных чисел. Если все элементы массива являются положительными, то вывести текст «YES», иначе вывести «NO».

ExamBegin36. На вход в первой строке подается целое положительное число N, а во второй строке — массив из N целых чисел. Если положительных чисел в массиве больше, чем отрицательных, то вывести символ «+», если отрицательных чисел больше, чем положительных, то вывести «−», если количество положительных чисел равно количеству отрицательных, то вывести «=».

ExamBegin37. На вход в первой строке подается целое положительное число N, а во второй строке — массив из N вещественных чисел. Если элементы массива упорядочены по возрастанию, то вывести текст «YES», иначе вывести «NO».

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

ExamBegin39. На вход в первой строке подается целое положительное число N, а во второй строке — массив из N вещественных чисел. Если элементы массива упорядочены по возрастанию или по убыванию, то вывести текст «YES», иначе вывести «NO».

ExamBegin40. На вход в первой строке подается целое положительное число N, а во второй строке — массив из N целых чисел. Найти количество чисел, которые встречаются в массиве ровно один раз.

ExamBegin41. На вход в первой строке подается целое положительное число N, а во второй строке — массив из N целых чисел. Найти количество чисел, которые встречаются в массиве более двух раз.

ExamBegin42. На вход в первой строке подается целое положительное число N, а во второй строке — массив из N целых чисел. Найти сумму четных элементов массива. Если четные элементы отсутствуют, то вывести 0.

ExamBegin43. На вход в первой строке подается целое положительное число N, а во второй строке — массив из N целых чисел. Найти произведение положительных элементов массива. Если положительные элементы отсутствуют, то вывести 1.

ExamBegin44. На вход в первой строке подается целое положительное число N, а во второй строке — массив из N вещественных чисел. Найти среднее арифметическое всех элементов массива, абсолютное значение которых (т. е. их модуль) меньше 10. Если требуемые элементы отсутствуют, то вывести текст «NO».

Минимумы и максимумы

ExamBegin45. На вход в первой строке подается целое положительное число N, а во второй строке — массив из N вещественных чисел. Найти минимальный и максимальный элементы массива и вывести их в указанном порядке (каждый элемент выводить на новой строке и снабжать комментарием «MIN=» или «MAX=»).

ExamBegin46. На вход в первой строке подается целое положительное число N, а во второй строке — массив из N целых чисел. Найти номер первого максимального элемента массива (элементы нумеруются от 1).

ExamBegin47. На вход в первой строке подается целое положительное число N, а во второй строке — массив из N целых чисел. Найти номер последнего минимального элемента массива (элементы нумеруются от 1).

ExamBegin48. На вход в первой строке подается целое положительное число N, а во второй строке — массив из N вещественных чисел. Найти максимальный отрицательный элемент массива. Если отрицательных элементов в массиве нет, то вывести текст «NO».

ExamBegin49. На вход в первой строке подается целое положительное число N, а во второй строке — массив из N целых чисел. Найти минимальный четный элемент массива. Если четных элементов в массиве нет, то вывести текст «NO».

ExamBegin50. На вход в первой строке подаются два вещественных числа A и B (A < B), во второй строке — целое положительное число N, а в третьей строке — массив из N вещественных чисел. Среди элементов массива, принадлежащих интервалу (A, B), найти минимальный и максимальный и вывести их в указанном порядке (каждое число выводить на новой строке и снабжать комментарием «MIN=» или «MAX=»). Если массив не содержит элементов, лежащих в интервале (A, B), то вывести текст «NO».

ExamBegin51. На вход в первой строке подается целое положительное число N, а во второй строке — массив из N целых чисел. Выполнив однократный просмотр массива, найти количество его минимальных элементов.

ExamBegin52. На вход в первой строке подается целое четное положительное число N, а во второй строке — массив из N целых чисел. Группируя элементы массива по парам (первый-второй, третий-четвертый и т. д.), найти за однократный просмотр массива количество пар с максимальной суммой и вывести в первой строке максимальную сумму, а во второй строке — количество пар с этой суммой.

ExamBegin53. На вход в первой строке подается целое число N (> 1), а во второй строке — массив из N различных вещественных чисел. Выполнив однократный просмотр массива, найти два его наименьших элемента и вывести эти элементы в порядке возрастания их значений (каждый элемент выводить на новой строке).

ExamBegin54. На вход в первой строке подается целое число N (> 2), а во второй строке — массив из N целых чисел, среди которых имеется не менее трех различных. Выполнив однократный просмотр массива, найти три его наибольших элемента с различными значениями и вывести эти элементы в порядке убывания их значений (каждый элемент выводить на новой строке).

ExamBegin55. На вход в первой строке подается целое положительное число N, а во второй строке — массив из N вещественных чисел. Выполнив однократный просмотр массива, найти максимальное количество подряд идущих положительных элементов. Если положительных элементов нет, то вывести 0.

ExamBegin56. На вход в первой строке подается целое положительное число N, а во второй строке — массив из N целых чисел. Выполнив однократный просмотр массива, найти максимальное количество подряд идущих одинаковых элементов.

ExamBegin57. На вход в первой строке подается целое число N (> 1), а во второй строке — массив из N целых чисел. Рассматривая всевозможные пары элементов массива, найти их максимальную сумму.

ExamBegin58. На вход в первой строке подается целое число N (> 1), а во второй строке — массив из N вещественных чисел. Рассматривая всевозможные пары элементов массива, найти пару элементов, сумма которых минимальна, и вывести номера этих элементов в порядке возрастания (элементы нумеруются от 1). Каждый номер выводить на новой строке. Предполагается, что в массиве имеется единственная пара элементов с минимальной суммой.

Анализ двумерных массивов

ExamBegin59. На вход в первой строке подается целое число A, во второй строке — целые положительные числа M и N, а в последующих M строках — двумерный целочисленный массив размера M × N. Найти количество строк массива, содержащих элемент со значением A.

ExamBegin60. На вход в первой строке подаются целые положительные числа M и N, а в последующих M строках — двумерный целочисленный массив размера M × N. Найти количество столбцов массива, содержащих хотя бы одно четное число.

ExamBegin61. На вход в первой строке подаются целые положительные числа M и N, а в последующих M строках — двумерный вещественный массив размера M × N. Найти количество строк массива, все элементы которых отрицательны.

ExamBegin62. На вход в первой строке подаются целые положительные числа M и N, а в последующих M строках — двумерный целочисленный массив размера M × N. Найти сумму элементов каждой строки массива (каждое найденное число выводить на новой экранной строке).

ExamBegin63. На вход в первой строке подаются целые положительные числа M и N, а в последующих M строках — двумерный вещественный массив размера M × N. Найти среднее арифметическое элементов каждого столбца массива (все найденные числа выводить в одной экранной строке, для каждого числа отводить 6 экранных позиций).

ExamBegin64. На вход в первой строке подаются целые положительные числа M и N, а в последующих M строках — двумерный целочисленный массив размера M × N. Найти сумму значений максимальных элементов всех строк массива.

ExamBegin65. На вход в первой строке подаются целые положительные числа M и N, а в последующих M строках — двумерный вещественный массив размера M × N. Найти произведение значений минимальных элементов всех столбцов массива.

ExamBegin66. На вход в первой строке подаются целые положительные числа M и N, а в последующих M строках — двумерный целочисленный массив размера M × N. Найти номер первой строки массива с минимальной суммой элементов (строки нумеруются от 1).

ExamBegin67. На вход в первой строке подаются целые положительные числа M и N, а в последующих M строках — двумерный целочисленный массив размера M × N. Найти номер последнего столбца массива с максимальной суммой элементов (столбцы нумеруются от 1).

ExamBegin68. На вход в первой строке подаются целые положительные числа M и N, а в последующих M строках — двумерный вещественный массив размера M × N. Найти номер столбца массива, содержащего максимальный из минимальных элементов всех столбцов (столбцы нумеруются от 1). Предполагается, что существует единственный столбец с требуемым свойством.

Преобразование массивов

ExamBegin69. На вход в первой строке подается целое положительное число N, а во второй строке — массив из N вещественных чисел. Выполнить циклический сдвиг элементов массива влево на одну позицию (при этом значения всех элементов, кроме первого, должны быть присвоены предыдущему элементу, а значение первого элемента — последнему элементу массива). Вывести преобразованный массив в одной строке, для каждого элемента отводить 7 экранных позиций.

ExamBegin70. На вход в первой строке подается целое положительное число N, а во второй строке — массив из N вещественных чисел. Выполнить циклический сдвиг элементов массива вправо на одну позицию (при этом значения всех элементов, кроме последнего, должны быть присвоены следующему элементу, а значение последнего элемента — первому элементу массива). Вывести преобразованный массив в одной строке, для каждого элемента отводить 7 экранных позиций.

ExamBegin71. На вход в первой строке подается целое положительное число N, а во второй строке — массив из N целых чисел. Поменять порядок следования элементов массива на обратный. Вывести преобразованный массив в одной строке, для каждого элемента отводить 5 экранных позиций.

ExamBegin72. На вход в первой строке подаются целые положительные числа K1, K2 и N (K1 ≤ K2 ≤ N), а во второй строке — массив из N вещественных чисел. Поменять в массиве порядок следования элементов с номерами от K1 до K2 включительно на обратный (элементы нумеруются от 1). Вывести преобразованный массив в одной строке, для каждого элемента отводить 7 экранных позиций.

ExamBegin73. На вход в первой строке подаются целые положительные числа K и N (K ≤ N), а во второй строке — массив из N вещественных чисел. Удалить из массива элемент с номером K (элементы нумеруются от 1). Вывести преобразованный массив в одной строке, для каждого элемента отводить 7 экранных позиций.

ExamBegin74. На вход в первой строке подаются целые положительные числа K1, K2 и N (K1 ≤ K2 < N), а во второй строке — массив из N вещественных чисел. Удалить из массива элементы с номерами от K1 до K2 включительно (элементы нумеруются от 1). Вывести преобразованный массив в одной строке, для каждого элемента отводить 7 экранных позиций.

ExamBegin75. На вход в первой строке подается целое положительное число N, а во второй строке — массив из N целых чисел. Удалить из массива все четные числа. Вывести в первой строке размер преобразованного массива. Если полученный массив не пуст, то вывести во второй строке его элементы; для каждого элемента отводить 4 экранные позиции.

ExamBegin76. На вход в первой строке подается целое положительное число N, а во второй строке — массив из N целых чисел. Удалить из массива все повторяющиеся элементы, оставив их первые вхождения. Вывести преобразованный массив в одной строке, для каждого элемента отводить 4 экранные позиции.

ExamBegin77. На вход в первой строке подаются целые положительные числа K и N (K ≤ N), а во второй строке — массив из N вещественных чисел. Продублировать в исходном массиве элемент с номером K (элементы нумеруются от 1). Вывести преобразованный массив в одной строке, для каждого элемента отводить 7 экранных позиций.

ExamBegin78. На вход в первой строке подаются целые положительные числа K и N (K ≤ N), а во второй строке — массив из N вещественных чисел. Вставить новый элемент со значением 1.0 перед элементом массива с порядковым номером K (элементы нумеруются от 1). Вывести преобразованный массив в одной строке, для каждого элемента отводить 7 экранных позиций.

ExamBegin79. На вход в первой строке подаются целые положительные числа K и N (K ≤ N), а во второй строке — массив из N вещественных чисел. Вставить новый элемент со значением 2.0 после элемента массива с порядковым номером K (элементы нумеруются от 1). Вывести преобразованный массив в одной строке, для каждого элемента отводить 7 экранных позиций.

ExamBegin80. На вход в первой строке подаются целые положительные числа K, M и N (K ≤ N), а во второй строке — массив из N целых чисел. Вставить M элементов со значением 0 перед элементом массива с порядковым номером K (элементы нумеруются от 1). Вывести преобразованный массив в одной строке, для каждого элемента отводить 4 экранные позиции.

ExamBegin81. На вход в первой строке подаются целые положительные числа K, M и N (K ≤ N), а во второй строке — массив из N целых чисел. Вставить M элементов со значением −1 после элемента массива с порядковым номером K (элементы нумеруются от 1). Вывести преобразованный массив в одной строке, для каждого элемента отводить 4 экранные позиции.

ExamBegin82. На вход в первой строке подается вещественное число A, во второй строке — целое положительное число N, а в третьей строке — массив из N вещественных чисел. Элементы массива упорядочены во возрастанию. Вставить число A в исходный массив с сохранением его упорядоченности. Вывести преобразованный массив в одной строке, для каждого элемента отводить 7 экранных позиций.

ExamBegin83. На вход в первой строке подается целое положительное число N, а во второй строке — массив из N вещественных чисел. Отсортировать элементы массива, упорядочив их по возрастанию. Вывести отсортированный массив в одной строке, для каждого элемента отводить 7 экранных позиций.

ExamBegin84. На вход в первой строке подаются целые положительные числа N1 и N2, во второй строке — массив из N1 целых чисел, а в третьей строке — массив из N2 целых чисел. Элементы обоих массивов упорядочены по возрастанию. Выполнить слияние элементов исходных массивов в результирующий массив из N1 + N2 чисел, сохранив упорядоченность элементов. Алгоритм сортировки не использовать. Вывести результирующий массив в одной строке, для каждого элемента отводить 4 экранные позиции.

Обработка текстовых данных

ExamBegin85. На вход подается текстовая строка, оканчивающаяся символом «.» (точка). Найти количество цифр в строке.

ExamBegin86. На вход подается текстовая строка, оканчивающаяся символом «.» (точка). Найти количество заглавных латинских букв в строке.

ExamBegin87. На вход в первой строке подается символ C — заглавная латинская буква, а во второй строке — строка S с текстом на английском языке, оканчивающаяся точкой. Найти частоту появления в строке S буквы C без учета ее регистра (частота является вещественным числом и определяется как отношение числа вхождений прописных и строчных букв C к общему числу символов в строке).

ExamBegin88. На вход подается текстовая строка. Заменить в строке строчные (т. е. маленькие) латинские буквы на соответствующие прописные (заглавные) и вывести преобразованную строку.

ExamBegin89. На вход в первой строке подается символ C, а во второй строке — текстовая строка S. Удалить из строки S все символы С и вывести преобразованную строку.

ExamBegin90. На вход в первой строке подается символ C, а во второй строке — текстовая строка S. Удвоить в строке S все символы С и вывести преобразованную строку (например, в случае C = «a», S = «abcad» надо вывести строку «aabcaad»).

ExamBegin91. На вход в первой строке подается непустая текстовая строка S0, а во второй строке — текстовая строка S. Найти количество неперекрывающихся вхождений строки S0 в строку S.

ExamBegin92. На вход в первой строке подается непустая текстовая строка S0, а во второй строке — текстовая строка S. Удалить из строки S первое вхождение строки S0 и вывести преобразованную строку S.

ExamBegin93. На вход в первой строке подается непустая текстовая строка S1, во второй строке — текстовая строка S2, а в третьей строке — текстовая строка S. Заменить в строке S последнее вхождение строки S1 на строку S2 и вывести преобразованную строку S.

ExamBegin94. На вход подается текстовая строка, содержащая набор слов, набранных заглавными латинскими буквами и разделенных ровно одним пробелом. Найти количество слов, начинающихся и оканчивающихся одной и той же буквой.

ExamBegin95. На вход подается текстовая строка, содержащая набор слов, набранных заглавными латинскими буквами и разделенных ровно одним пробелом. Найти количество слов, содержащих хотя бы одну букву «E».

ExamBegin96. На вход подается текстовая строка, содержащая набор слов, набранных заглавными латинскими буквами и разделенных ровно одним пробелом. Найти количество слов, содержащих ровно три буквы «Е».

ExamBegin97. На вход подается текстовая строка, содержащая набор слов, набранных заглавными латинскими буквами и разделенных ровно одним пробелом. Найти самое длинное слово в строке. Если таких слов несколько, то вывести первое из них.

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

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

ExamBegin100. На вход подается текстовая строка, содержащая набор слов, набранных заглавными латинскими буквами и разделенных ровно одним пробелом. Сформировать и вывести строку, содержащую те же слова, разделенные одним пробелом и расположенные в порядке возрастания их длины, а для слов равной длины — в алфавитном порядке.


Группы заданий

ЕГЭ по информатике, задачи повышенной сложности: группа ExamTaskC

[Перейти к указаниям] [Перейти к началу раздела «Группы заданий»] [Перейти к началу раздела «Указания»]

При выполнении заданий данной группы вместо специальных операций ввода-вывода, предоставляемых задачником, необходимо применять стандартные операции используемого языка программирования: процедуры Read/Readln–Write/Writeln для языка Pascal и потоки cin–cout для языка C++.

Во всех заданиях предполагается, что элементы как исходных, так и результирующих данных разделяются ровно одним пробелом, а в начале и конце каждой строки пробелы отсутствуют. Длина каждого строкового элемента исходных данных не превосходит 20 символов, инициалы не содержат пробелов и всегда состоят из 4 символов (заглавные буквы имени и отчества, за которыми указываются точки, например, A.Б.). Если числа содержат дробную часть, то она отделяется от целой части десятичной точкой.

Обработка сложных наборов данных

ExamTaskC1. На вход подаются сведения о клиентах фитнес-центра. В первой строке указывается целое число N, а каждая из последующих N строк имеет формат

<Код клиента> <Год> <Номер месяца> <Продолжительность занятий (в часах)>

Все данные целочисленные. Значение года лежит в диапазоне от 2000 до 2010, код клиента — в диапазоне 10−99, продолжительность занятий — в диапазоне 1−30. Найти строку исходных данных с минимальной продолжительностью занятий. Вывести эту продолжительность, а также соответствующие ей год и номер месяца (в указанном порядке). Если имеется несколько строк с минимальной продолжительностью, то вывести данные той из них, которая является последней в исходном наборе.

ExamTaskC2. На вход подаются сведения о клиентах фитнес-центра. В первой строке указывается целое число N, а каждая из последующих N строк имеет формат

<Год> <Номер месяца> <Продолжительность занятий (в часах)> <Код клиента>

Все данные целочисленные. Значение года лежит в диапазоне от 2000 до 2010, код клиента — в диапазоне 10−99, продолжительность занятий — в диапазоне 1−30. Найти строку исходных данных с максимальной продолжительностью занятий. Вывести эту продолжительность, а также соответствующие ей год и номер месяца (в указанном порядке). Если имеется несколько строк с максимальной продолжительностью, то вывести данные той из них, которая является первой в исходном наборе.

ExamTaskC3. На вход подаются сведения о клиентах фитнес-центра. В первой строке указывается целое число N, а каждая из последующих N строк имеет формат

<Продолжительность занятий (в часах)> <Код клиента> <Год> <Номер месяца>

Все данные целочисленные. Значение года лежит в диапазоне от 2000 до 2010, код клиента — в диапазоне 10−99, продолжительность занятий — в диапазоне 1−30. Найти строку исходных данных с минимальной продолжительностью занятий. Вывести эту продолжительность, а также соответствующие ей год и номер месяца (в указанном порядке). Если имеется несколько строк с минимальной продолжительностью, то вывести данные, соответствующие самой ранней дате.

ExamTaskC4. На вход подаются сведения о клиентах фитнес-центра. В первой строке указывается целое число N, а каждая из последующих N строк имеет формат

<Номер месяца> <Год> <Код клиента> <Продолжительность занятий (в часах)>

Все данные целочисленные. Значение года лежит в диапазоне от 2000 до 2010, код клиента — в диапазоне 10−99, продолжительность занятий — в диапазоне 1−30. Найти строку исходных данных с максимальной продолжительностью занятий. Вывести эту продолжительность, а также соответствующие ей год и номер месяца (в указанном порядке). Если имеется несколько строк с максимальной продолжительностью, то вывести данные, соответствующие самой поздней дате.

ExamTaskC5. На вход подаются сведения о клиентах фитнес-центра. В первой строке указывается целое число N, а каждая из последующих N строк имеет формат

<Год> <Номер месяца> <Продолжительность занятий (в часах)> <Код клиента>

Все данные целочисленные. Значение года лежит в диапазоне от 2000 до 2010, код клиента — в диапазоне 10−99, продолжительность занятий — в диапазоне 1−30. Определить год, в котором суммарная продолжительность занятий всех клиентов была наибольшей, и вывести этот год и наибольшую суммарную продолжительность. Если таких годов было несколько, то вывести наименьший из них.

ExamTaskC6. На вход подаются сведения о клиентах фитнес-центра. В первой строке указывается целое число N, а каждая из последующих N строк имеет формат

<Продолжительность занятий (в часах)> <Год> <Номер месяца> <Код клиента>

Все данные целочисленные. Значение года лежит в диапазоне от 2000 до 2010, код клиента — в диапазоне 10−99, продолжительность занятий — в диапазоне 1−30. Определить год, в котором суммарная продолжительность занятий всех клиентов была наименьшей (годы с нулевой продолжительностью не учитывать), и вывести этот год и наименьшую суммарную продолжительность. Если таких годов было несколько, то вывести наибольший из них.

ExamTaskC7. На вход подаются сведения о клиентах фитнес-центра. В первой строке указывается целое число N, а каждая из последующих N строк имеет формат

<Продолжительность занятий (в часах)> <Код клиента> <Год> <Номер месяца>

Все данные целочисленные. Значение года лежит в диапазоне от 2000 до 2010, код клиента — в диапазоне 10−99, продолжительность занятий — в диапазоне 1−30. Для каждого клиента, присутствующего в исходных данных, определить суммарную продолжительность занятий в течение всех лет (вначале выводить код клиента, затем суммарную продолжительность). Сведения о каждом клиенте выводить на новой строке и упорядочивать по возрастанию кода клиента.

ExamTaskC8. На вход подаются сведения о клиентах фитнес-центра. В первой строке указывается целое число N, а каждая из последующих N строк имеет формат

<Код клиента> <Год> <Номер месяца> <Продолжительность занятий (в часах)>

Все данные целочисленные. Значение года лежит в диапазоне от 2000 до 2010, код клиента — в диапазоне 10−99, продолжительность занятий — в диапазоне 1−30. Для каждого клиента, присутствующего в исходных данных, определить общее количество месяцев, в течение которых он посещал занятия (вначале выводить код клиента, затем количество месяцев). Сведения о каждом клиенте выводить на новой строке и упорядочивать по возрастанию кода клиента.

ExamTaskC9. На вход подаются сведения о клиентах фитнес-центра. В первой строке указывается целое число N, а каждая из последующих N строк имеет формат

<Год> <Номер месяца> <Продолжительность занятий (в часах)> <Код клиента>

Все данные целочисленные. Значение года лежит в диапазоне от 2000 до 2010, код клиента — в диапазоне 10−99, продолжительность занятий — в диапазоне 1−30. Для каждого клиента, присутствующего в исходных данных, определить суммарную продолжительность занятий в течение всех лет (вначале выводить суммарную продолжительность, затем код клиента). Сведения о каждом клиенте выводить на новой строке и упорядочивать по убыванию суммарной продолжительности, а при их равенстве — по возрастанию кода клиента.

ExamTaskC10. На вход подаются сведения о клиентах фитнес-центра. В первой строке указывается целое число N, а каждая из последующих N строк имеет формат

<Код клиента> <Продолжительность занятий (в часах)> <Год> <Номер месяца>

Все данные целочисленные. Значение года лежит в диапазоне от 2000 до 2010, код клиента — в диапазоне 10−99, продолжительность занятий — в диапазоне 1−30. Для каждого клиента, присутствующего в исходных данных, определить общее количество месяцев, в течение которых он посещал занятия (вначале выводить количество месяцев, затем код клиента). Сведения о каждом клиенте выводить на новой строке и упорядочивать по возрастанию количества месяцев, а при их равенстве — по возрастанию кода клиента.

ExamTaskC11. На вход подаются сведения о клиентах фитнес-центра. В первой строке указывается целое число N, а каждая из последующих N строк имеет формат

<Год> <Номер месяца> <Код клиента> <Продолжительность занятий (в часах)>

Все данные целочисленные. Значение года лежит в диапазоне от 2000 до 2010, код клиента — в диапазоне 10−99, продолжительность занятий — в диапазоне 1−30. Для каждого месяца определить суммарную продолжительность занятий всех клиентов за все годы (вначале выводить номер месяца, затем суммарную продолжительность). Если данные о некотором месяце отсутствуют, то для этого месяца вывести 0. Сведения о каждом месяце выводить на новой строке и упорядочивать по возрастанию номера месяца.

ExamTaskC12. На вход подаются сведения о клиентах фитнес-центра. В первой строке указывается целое число N, а каждая из последующих N строк имеет формат

<Код клиента> <Продолжительность занятий (в часах)> <Год> <Номер месяца>

Все данные целочисленные. Значение года лежит в диапазоне от 2000 до 2010, код клиента — в диапазоне 10−99, продолжительность занятий — в диапазоне 1−30. Для каждого месяца определить суммарную продолжительность занятий всех клиентов за все годы (вначале выводить суммарную продолжительность, затем номер месяца). Если данные о некотором месяце отсутствуют, то для этого месяца вывести 0. Сведения о каждом месяце выводить на новой строке и упорядочивать по убыванию суммарной продолжительности, а при равной продолжительности — по возрастанию номера месяца.

ExamTaskC13. На вход подаются сведения о клиентах фитнес-центра. В первой строке указывается код K одного из клиентов, во второй строке — целое число N, а каждая из последующих N строк имеет формат

<Продолжительность занятий (в часах)> <Год> <Номер месяца> <Код клиента>

Все данные целочисленные. Значение года лежит в диапазоне от 2000 до 2010, код клиента — в диапазоне 10−99, продолжительность занятий — в диапазоне 1−30. Для каждого года, в котором клиент с кодом K посещал центр, определить месяц, в котором продолжительность занятий данного клиента была наибольшей для данного года (если таких месяцев несколько, то выбирать месяц с наименьшим номером). Сведения о каждом годе выводить на новой строке в следующем порядке: год, номер месяца, продолжительность занятий в этом месяце. Упорядочивать сведения по убыванию номера года. Если данные о клиенте с кодом K отсутствуют, то вывести строку «Нет данных».

ExamTaskC14. На вход подаются сведения о клиентах фитнес-центра. В первой строке указывается код K одного из клиентов, во второй строке — целое число N, а каждая из последующих N строк имеет формат

<Год> <Номер месяца> <Код клиента> <Продолжительность занятий (в часах)>

Все данные целочисленные. Значение года лежит в диапазоне от 2000 до 2010, код клиента — в диапазоне 10−99, продолжительность занятий — в диапазоне 1−30. Для каждого года, в котором клиент с кодом K посещал центр, определить месяц, в котором продолжительность занятий данного клиента была наименьшей для данного года (если таких месяцев несколько, то выбирать месяц с наибольшим номером; месяцы с нулевой продолжительностью занятий не учитывать). Сведения о каждом годе выводить на новой строке в следующем порядке: год, номер месяца, продолжительность занятий в этом месяце. Упорядочивать сведения по возрастанию номера года. Если данные о клиенте с кодом K отсутствуют, то вывести строку «Нет данных».

ExamTaskC15. На вход подаются сведения о клиентах фитнес-центра. В первой строке указывается код K одного из клиентов, во второй строке — целое число N, а каждая из последующих N строк имеет формат

<Код клиента> <Продолжительность занятий (в часах)> <Год> <Номер месяца>

Все данные целочисленные. Значение года лежит в диапазоне от 2000 до 2010, код клиента — в диапазоне 10−99, продолжительность занятий — в диапазоне 1−30. Для каждого года, в котором клиент с кодом K посещал центр, определить месяц, в котором продолжительность занятий данного клиента была наибольшей для данного года (если таких месяцев несколько, то выбирать месяц с наименьшим номером). Сведения о каждом годе выводить на новой строке в следующем порядке: наибольшая продолжительность занятий в году, год, номер месяца. Упорядочивать сведения по убыванию продолжительности занятий, а при равной продолжительности — по возрастанию номера года. Если данные о клиенте с кодом K отсутствуют, то вывести строку «Нет данных».

ExamTaskC16. На вход подаются сведения о клиентах фитнес-центра. В первой строке указывается код K одного из клиентов, во второй строке — целое число N, а каждая из последующих N строк имеет формат

<Продолжительность занятий (в часах)> <Код клиента> <Год> <Номер месяца>

Все данные целочисленные. Значение года лежит в диапазоне от 2000 до 2010, код клиента — в диапазоне 10−99, продолжительность занятий — в диапазоне 1−30. Для каждого года, в котором клиент с кодом K посещал центр, определить месяц, в котором продолжительность занятий данного клиента была наименьшей для данного года (если таких месяцев несколько, то выбирать месяц с наибольшим номером; месяцы с нулевой продолжительностью занятий не учитывать). Сведения о каждом годе выводить на новой строке в следующем порядке: наименьшая продолжительность занятий, год, номер месяца. Упорядочивать сведения по возрастанию продолжительности занятий, а при равной продолжительности — по возрастанию номера года. Если данные о клиенте с кодом K отсутствуют, то вывести строку «Нет данных».

ExamTaskC17. На вход подаются сведения о клиентах фитнес-центра. В первой строке указывается код K одного из клиентов, во второй строке — целое число N, а каждая из последующих N строк имеет формат

<Номер месяца> <Год> <Код клиента> <Продолжительность занятий (в часах)>

Все данные целочисленные. Значение года лежит в диапазоне от 2000 до 2010, код клиента — в диапазоне 10−99, продолжительность занятий — в диапазоне 1−30. Для каждого года, в котором клиент с кодом K посещал центр, определить число месяцев, для которых продолжительность занятий данного клиента превосходила 15 часов (вначале выводить год, затем число месяцев). Если для некоторого года требуемые месяцы отсутствуют, то вывести для него 0. Сведения о каждом годе выводить на новой строке; данные упорядочивать по возрастанию номера года. Если данные об указанном клиенте отсутствуют, то вывести строку «Нет данных».

ExamTaskC18. На вход подаются сведения о клиентах фитнес-центра. В первой строке указывается код K одного из клиентов, во второй строке — целое число N, а каждая из последующих N строк имеет формат

<Код клиента> <Продолжительность занятий (в часах)> <Номер месяца> <Год>

Все данные целочисленные. Значение года лежит в диапазоне от 2000 до 2010, код клиента — в диапазоне 10−99, продолжительность занятий — в диапазоне 1−30. Для каждого года, в котором клиент с кодом K посещал центр, определить число месяцев, для которых продолжительность занятий данного клиента превосходила 15 часов (вначале выводить число месяцев, затем год). Если для некоторого года требуемые месяцы отсутствуют, то вывести для него 0. Сведения о каждом годе выводить на новой строке; данные упорядочивать по убыванию числа месяцев, а при равном числе месяцев — по возрастанию номера года. Если данные об указанном клиенте отсутствуют, то вывести строку «Нет данных».

ExamTaskC19. На вход подаются сведения о клиентах фитнес-центра. В первой строке указывается целое число N, а каждая из последующих N строк имеет формат

<Год> <Номер месяца> <Код клиента> <Продолжительность занятий (в часах)>

Все данные целочисленные. Значение года лежит в диапазоне от 2000 до 2010, код клиента — в диапазоне 10−99, продолжительность занятий — в диапазоне 1−30. Для каждой пары «год−месяц», присутствующей в исходных данных, определить количество клиентов, которые посещали центр в указанное время (вначале выводится год, затем месяц, затем количество клиентов). Сведения о каждой паре «год−месяц» выводить на новой строке и упорядочивать по убыванию номера года, а для одинакового номера года — по возрастанию номера месяца.

ExamTaskC20. На вход подаются сведения о клиентах фитнес-центра. В первой строке указывается целое число N, а каждая из последующих N строк имеет формат

<Код клиента> <Продолжительность занятий (в часах)> <Год> <Номер месяца>

Все данные целочисленные. Значение года лежит в диапазоне от 2000 до 2010, код клиента — в диапазоне 10−99, продолжительность занятий — в диапазоне 1−30. Для каждой пары «год−месяц», присутствующей в исходных данных, определить общую продолжительность занятий всех клиентов в указанное время (вначале выводится год, затем месяц, затем общая продолжительность). Сведения о каждой паре «год−месяц» выводить на новой строке и упорядочивать по возрастанию номера года, а для одинакового номера года — по возрастанию номера месяца.

ExamTaskC21. На вход подаются сведения о клиентах фитнес-центра. В первой строке указывается целое число N, а каждая из последующих N строк имеет формат

<Продолжительность занятий (в часах)> <Год> <Номер месяца> <Код клиента>

Все данные целочисленные. Значение года лежит в диапазоне от 2000 до 2010, код клиента — в диапазоне 10−99, продолжительность занятий — в диапазоне 1−30. Для каждой пары «год−месяц», присутствующей в исходных данных, определить количество клиентов, которые посещали центр в указанное время (вначале выводится количество клиентов, затем год, затем месяц). Сведения о каждой паре «год−месяц» выводить на новой строке и упорядочивать по убыванию количества клиентов, для одинакового количества клиентов — по возрастанию номера года, а для одинакового номера года — по возрастанию номера месяца.

ExamTaskC22. На вход подаются сведения о клиентах фитнес-центра. В первой строке указывается целое число N, а каждая из последующих N строк имеет формат

<Код клиента> <Год> <Номер месяца> <Продолжительность занятий (в часах)>

Все данные целочисленные. Значение года лежит в диапазоне от 2000 до 2010, код клиента — в диапазоне 10−99, продолжительность занятий — в диапазоне 1−30. Для каждой пары «год−месяц», присутствующей в исходных данных, определить общую продолжительность занятий всех клиентов в указанное время (вначале выводится общая продолжительность, затем год, затем месяц). Сведения о каждой паре «год−месяц» выводить на новой строке и упорядочивать по возрастанию общей продолжительности занятий, для одинаковой продолжительности — по убыванию номера года, а для одинакового номера года — по возрастанию номера месяца.

ExamTaskC23. На вход подаются сведения о клиентах фитнес-центра. В первой строке указывается целое число N, а каждая из последующих N строк имеет формат

<Номер месяца> <Год> <Продолжительность занятий (в часах)> <Код клиента>

Все данные целочисленные. Значение года лежит в диапазоне от 2000 до 2010, код клиента — в диапазоне 10−99, продолжительность занятий — в диапазоне 1−30. Для каждого года, присутствующего в исходных данных, определить месяцы, в которых суммарная длительность занятий всех клиентов составляла более 25 % от суммарной длительности за этот год (вначале выводить год, затем месяцы по возрастанию их номеров). Если в некотором году ни для одного месяца не выполнялось требуемое условие, то после номера года выводить текст «Нет». Сведения о каждом годе выводить на новой строке и упорядочивать по возрастанию номера года.

ExamTaskC24. На вход подаются сведения о клиентах фитнес-центра. В первой строке указывается целое число N, а каждая из последующих N строк имеет формат

<Продолжительность занятий (в часах)> <Код клиента> <Номер месяца> <Год>

Все данные целочисленные. Значение года лежит в диапазоне от 2000 до 2010, код клиента — в диапазоне 10−99, продолжительность занятий — в диапазоне 1−30. Для каждого года, присутствующего в исходных данных, определить количество месяцев, в которых суммарная длительность занятий всех клиентов составляла более 15 % от суммарной длительности за этот год (вначале выводить количество месяцев, затем год). Если в некотором году ни для одного месяца не выполнялось требуемое условие, то вывести для него 0. Сведения о каждом годе выводить на новой строке и упорядочивать по убыванию количества месяцев, а для одинакового количества — по возрастанию номера года.

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

<Номер школы> <Год поступления> <Фамилия>

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

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

<Год поступления> <Номер школы> <Фамилия>

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

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

<Номер школы> <Год поступления> <Фамилия>

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

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

<Год поступления> <Номер школы> <Фамилия>

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

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

<Номер школы> <Год поступления> <Фамилия>

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

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

<Год поступления> <Номер школы> <Фамилия>

Номер школы содержит не более двух цифр, годы лежат в диапазоне от 1990 до 2010. Найти годы, для которых число абитуриентов было не меньше среднего значение по всем годам (вначале указывать число абитуриентов для данного года, затем год). При вычислении среднего значения учитывать только годы, присутствующие в исходных данных; среднее значение может иметь ненулевую дробную часть. Сведения о каждом годе выводить на новой строке и упорядочивать по убыванию числа абитуриентов, а для совпадающих чисел — по возрастанию номера года.

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

<Фамилия> <Год поступления> <Номер школы>

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

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

<Фамилия> <Номер школы> <Год поступления>

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

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

<Фамилия> <Год поступления> <Номер школы>

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

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

<Фамилия> <Номер школы> <Год поступления>

Номер школы содержит не более двух цифр, годы лежат в диапазоне от 1990 до 2010. Для каждого номера школы, присутствующего в исходных данных, вывести общее число абитуриентов за все годы (вначале указывать число абитуриентов, затем номер школы). Сведения о каждой школе выводить на новой строке и упорядочивать по возрастанию числа абитуриентов, а для одинаковых чисел — по возрастанию номеров школ.

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

<Фамилия> <Год поступления> <Номер школы>

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

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

<Фамилия> <Номер школы> <Год поступления>

Номер школы содержит не более двух цифр, годы лежат в диапазоне от 1990 до 2010. Найти школы, для которых общее число абитуриентов за все годы было не меньше среднего значения по всем школам (вначале указывать число абитуриентов для данной школы, затем номер школы). При вычислении среднего значения учитывать только школы, присутствующие в исходных данных; среднее значение может иметь ненулевую дробную часть. Сведения о каждой школе выводить на новой строке и упорядочивать по возрастанию числа абитуриентов, а для одинаковых чисел — по убыванию номера школы.

ExamTaskC37. На вход подаются сведения о задолженности по оплате коммунальных услуг жильцов 144-квартирного 9-этажного дома. В первой строке указывается общее число задолжников N. Каждая из последующих N строк содержит информацию об одном из задолжников в формате

<Номер квартиры> <Фамилия> <Задолженность>

Задолженность указывается в виде дробного числа (целая часть — рубли, дробная часть — копейки). В каждом подъезде на каждом этаже располагаются по 4 квартиры. Для каждого из 4 подъездов дома вывести сведения о задолжниках, живущих в этом подъезде: номер подъезда, число задолжников, средняя задолженность для жильцов этого подъезда (выводится с двумя дробными знаками). Жильцы, не имеющие долга, при вычислении средней задолженности не учитываются. Сведения о каждом подъезде выводить на отдельной строке и упорядочивать по возрастанию номера подъезда. Если в каком-либо подъезде задолжники отсутствуют, то данные об этом подъезде не выводить.

ExamTaskC38. На вход подаются сведения о задолженности по оплате коммунальных услуг жильцов 144-квартирного 9-этажного дома. В первой строке указывается общее число задолжников N. Каждая из последующих N строк содержит информацию об одном из задолжников в формате

<Фамилия> <Задолженность> <Номер квартиры>

Задолженность указывается в виде дробного числа (целая часть — рубли, дробная часть — копейки). В каждом подъезде на каждом этаже располагаются по 4 квартиры. Для каждого из 4 подъездов дома вывести сведения о задолжниках, живущих в этом подъезде: число задолжников, номер подъезда, средняя задолженность для жильцов этого подъезда (выводится с двумя дробными знаками). Жильцы, не имеющие долга, при вычислении средней задолженности не учитываются. Сведения о каждом подъезде выводить на отдельной строке и упорядочивать по убыванию числа задолжников, а для совпадающих чисел — по возрастанию номера подъезда. Если в каком-либо подъезде задолжники отсутствуют, то данные об этом подъезде не выводить.

ExamTaskC39. На вход подаются сведения о задолженности по оплате коммунальных услуг жильцов 144-квартирного 9-этажного дома. В первой строке указывается общее число задолжников N. Каждая из последующих N строк содержит информацию об одном из задолжников в формате

<Задолженность> <Фамилия> <Номер квартиры>

Задолженность указывается в виде дробного числа (целая часть — рубли, дробная часть — копейки). В каждом подъезде на каждом этаже располагаются по 4 квартиры. Для каждого из 9 этажей дома вывести сведения о задолжниках, живущих на этом этаже: номер этажа, суммарная задолженность для жильцов этого этажа (выводится с двумя дробными знаками), число задолжников. Сведения о каждом этаже выводить на отдельной строке и упорядочивать по убыванию номера этажа. Если на каком-либо этаже задолжники отсутствуют, то данные об этом этаже не выводить.

ExamTaskC40. На вход подаются сведения о задолженности по оплате коммунальных услуг жильцов 144-квартирного 9-этажного дома. В первой строке указывается общее число задолжников N. Каждая из последующих N строк содержит информацию об одном из задолжников в формате

<Фамилия> <Номер квартиры> <Задолженность>

Задолженность указывается в виде дробного числа (целая часть — рубли, дробная часть — копейки). В каждом подъезде на каждом этаже располагаются по 4 квартиры. Для каждого из 9 этажей дома вывести сведения о задолжниках, живущих на этом этаже: число задолжников, номер этажа, суммарная задолженность для жильцов этого этажа (выводится с двумя дробными знаками). Сведения о каждом этаже выводить на отдельной строке и упорядочивать по возрастанию числа задолжников, а для совпадающих чисел — по возрастанию этажа. Если на каком-либо этаже задолжники отсутствуют, то данные об этом этаже не выводить.

ExamTaskC41. На вход подаются сведения о задолженности по оплате коммунальных услуг жильцов 144-квартирного 9-этажного дома. В первой строке указывается общее число задолжников N. Каждая из последующих N строк содержит информацию об одном из задолжников в формате

<Номер квартиры> <Фамилия> <Задолженность>

Задолженность указывается в виде дробного числа (целая часть — рубли, дробная часть — копейки). В каждом подъезде на каждом этаже располагаются по 4 квартиры. Для каждого из 4 подъездов дома найти жильца с наибольшей задолженностью и вывести сведения о нем: номер подъезда, номер квартиры, фамилия жильца, задолженность (выводится с двумя дробными знаками). Считать, что в наборе исходных данных все задолженности имеют различные значения. Сведения о каждом задолжнике выводить на отдельной строке и упорядочивать по возрастанию номера подъезда. Если в каком-либо подъезде задолжники отсутствуют, то данные об этом подъезде не выводить.

ExamTaskC42. На вход подаются сведения о задолженности по оплате коммунальных услуг жильцов 144-квартирного 9-этажного дома. В первой строке указывается общее число задолжников N. Каждая из последующих N строк содержит информацию об одном из задолжников в формате

<Задолженность> <Фамилия> <Номер квартиры>

Задолженность указывается в виде дробного числа (целая часть — рубли, дробная часть — копейки). В каждом подъезде на каждом этаже располагаются по 4 квартиры. Для каждого из 4 подъездов дома найти жильца с наибольшей задолженностью и вывести сведения о нем: задолженность (выводится с двумя дробными знаками), номер подъезда, номер квартиры, фамилия жильца. Считать, что в наборе исходных данных все задолженности имеют различные значения. Сведения о каждом задолжнике выводить на отдельной строке и упорядочивать по убыванию размера задолженности. Если в каком-либо подъезде задолжники отсутствуют, то данные об этом подъезде не выводить.

ExamTaskC43. На вход подаются сведения о задолженности по оплате коммунальных услуг жильцов 144-квартирного 9-этажного дома. В первой строке указывается общее число задолжников N. Каждая из последующих N строк содержит информацию об одном из задолжников в формате

<Фамилия> <Задолженность> <Номер квартиры>

Задолженность указывается в виде дробного числа (целая часть — рубли, дробная часть — копейки). В каждом подъезде на каждом этаже располагаются по 4 квартиры. Для каждого из 9 этажей дома найти жильца с наименьшей задолженностью и вывести сведения о нем: номер квартиры, номер этажа, фамилия жильца, задолженность (выводится с двумя дробными знаками). Считать, что в наборе исходных данных все задолженности имеют различные значения. Сведения о каждом задолжнике выводить на отдельной строке и упорядочивать по возрастанию номера квартиры. Если на каком-либо этаже задолжники отсутствуют, то данные об этом этаже не выводить.

ExamTaskC44. На вход подаются сведения о задолженности по оплате коммунальных услуг жильцов 144-квартирного 9-этажного дома. В первой строке указывается общее число задолжников N. Каждая из последующих N строк содержит информацию об одном из задолжников в формате

<Фамилия> <Номер квартиры> <Задолженность>

Задолженность указывается в виде дробного числа (целая часть — рубли, дробная часть — копейки). В каждом подъезде на каждом этаже располагаются по 4 квартиры. Для каждого из 9 этажей дома найти жильца с наименьшей задолженностью и вывести сведения о нем: задолженность (выводится с двумя дробными знаками), номер этажа, номер квартиры, фамилия жильца. Считать, что в наборе исходных данных все задолженности имеют различные значения. Сведения о каждом задолжнике выводить на отдельной строке и упорядочивать по убыванию размера задолженности. Если на каком-либо этаже задолжники отсутствуют, то данные об этом этаже не выводить.

ExamTaskC45. На вход подаются сведения о задолженности по оплате коммунальных услуг жильцов 144-квартирного 9-этажного дома. В первой строке указывается общее число задолжников N. Каждая из последующих N строк содержит информацию об одном из задолжников в формате

<Номер квартиры> <Задолженность> <Фамилия>

Задолженность указывается в виде дробного числа (целая часть — рубли, дробная часть — копейки). В каждом подъезде на каждом этаже располагаются по 4 квартиры. Найти жильцов, долг которых не меньше величины средней задолженности по дому, и вывести сведения о них: номер квартиры, фамилия, задолженность (выводится с двумя дробными знаками). Жильцы, не имеющие долга, при вычислении средней задолженности не учитываются. Сведения о каждом задолжнике выводить на отдельной строке и упорядочивать по возрастанию номеров квартир.

ExamTaskC46. На вход подаются сведения о задолженности по оплате коммунальных услуг жильцов 144-квартирного 9-этажного дома. В первой строке указывается общее число задолжников N. Каждая из последующих N строк содержит информацию об одном из задолжников в формате

<Задолженность> <Номер квартиры> <Фамилия>

Задолженность указывается в виде дробного числа (целая часть — рубли, дробная часть — копейки). В каждом подъезде на каждом этаже располагаются по 4 квартиры. Найти жильцов, долг которых не больше величины средней задолженности по дому, и вывести сведения о них: номер этажа, номер квартиры, фамилия, задолженность (выводится с двумя дробными знаками). Жильцы, не имеющие долга, при вычислении средней задолженности не учитываются. Сведения о каждом задолжнике выводить на отдельной строке и упорядочивать по убыванию номеров этажей, а для одинаковых этажей — по возрастанию номеров квартир.

ExamTaskC47. На вход подаются сведения о задолженности по оплате коммунальных услуг жильцов 144-квартирного 9-этажного дома. В первой строке указывается общее число задолжников N. Каждая из последующих N строк содержит информацию об одном из задолжников в формате

<Задолженность> <Фамилия> <Номер квартиры>

Задолженность указывается в виде дробного числа (целая часть — рубли, дробная часть — копейки). В каждом подъезде на каждом этаже располагаются по 4 квартиры. Для каждого из 4 подъездов дома найти задолжников, долг которых не меньше величины средней задолженности по данному подъезду, и вывести сведения о них: номер подъезда, задолженность (выводится с двумя дробными знаками), фамилия, номер квартиры. Жильцы, не имеющие долга, при вычислении средней задолженности не учитываются. Сведения о каждом задолжнике выводить на отдельной строке и упорядочивать по возрастанию номеров подъездов, а для одинаковых подъездов — по убыванию размера задолженности. Считать, что в наборе исходных данных все задолженности имеют различные значения.

ExamTaskC48. На вход подаются сведения о задолженности по оплате коммунальных услуг жильцов 144-квартирного 9-этажного дома. В первой строке указывается общее число задолжников N. Каждая из последующих N строк содержит информацию об одном из задолжников в формате

<Номер квартиры> <Фамилия> <Задолженность>

Задолженность указывается в виде дробного числа (целая часть — рубли, дробная часть — копейки). В каждом подъезде на каждом этаже располагаются по 4 квартиры. Для каждого из 9 этажей дома найти задолжников, долг которых не больше величины средней задолженности по данному этажу, и вывести сведения о них: номер этажа, задолженность (выводится с двумя дробными знаками), фамилия, номер квартиры. Жильцы, не имеющие долга, при вычислении средней задолженности не учитываются. Сведения о каждом задолжнике выводить на отдельной строке и упорядочивать по возрастанию номеров этажей, а для одинаковых этажей — по возрастанию размера задолженности. Считать, что в наборе исходных данных все задолженности имеют различные значения.

ExamTaskC49. На вход подаются сведения о ценах на бензин на автозаправочных станциях (АЗС). В первой строке содержится число N, каждая из последующих N строк имеет формат

<Компания> <Марка бензина> <Цена 1 литра (в копейках)> <Улица>

Имеется не более 20 различных компаний и не более 30 различных улиц; названия компаний и улиц не содержат пробелов. В качестве марки бензина указываются числа 92, 95 или 98. Цена задается целым числом в диапазоне от 2000 до 3000. Каждая компания имеет не более одной АЗС на каждой улице; цены на разных АЗС одной и той же компании могут различаться. Для каждой марки бензина, присутствующей в исходных данных, определить минимальную и максимальную цену литра бензина этой марки (вначале выводить марку, затем цены в указанном порядке). Сведения о каждой марке выводить на новой строке и упорядочивать по убыванию значения марки.

ExamTaskC50. На вход подаются сведения о ценах на бензин на автозаправочных станциях (АЗС). В первой строке содержится число N, каждая из последующих N строк имеет формат

<Цена 1 литра (в копейках)> <Марка бензина> <Компания> <Улица>

Имеется не более 20 различных компаний и не более 30 различных улиц; названия компаний и улиц не содержат пробелов. В качестве марки бензина указываются числа 92, 95 или 98. Цена задается целым числом в диапазоне от 2000 до 3000. Каждая компания имеет не более одной АЗС на каждой улице; цены на разных АЗС одной и той же компании могут различаться. Для каждой марки бензина, присутствующей в исходных данных, определить количество станций, предлагавших эту марку (вначале выводить количество станций, затем номер марки). Сведения о каждой марке выводить на новой строке и упорядочивать по возрастанию количества станций, а для одинакового количества — по возрастанию значения марки.

ExamTaskC51. На вход подаются сведения о ценах на бензин на автозаправочных станциях (АЗС). В первой строке содержится значение M одной из марок бензина, во второй строке указывается целое число N, а каждая из последующих N строк имеет формат

<Улица> <Компания> <Марка бензина> <Цена 1 литра (в копейках)>

Имеется не более 20 различных компаний и не более 30 различных улиц; названия компаний и улиц не содержат пробелов. В качестве марки бензина указываются числа 92, 95 или 98. Цена задается целым числом в диапазоне от 2000 до 3000. Каждая компания имеет не более одной АЗС на каждой улице; цены на разных АЗС одной и той же компании могут различаться. Для каждой улицы определить количество АЗС, предлагавших марку бензина M (вначале выводить количество АЗС на данной улице, затем название улицы; количество АЗС может быть равно 0). Сведения о каждой улице выводить на новой строке и упорядочивать по возрастанию количества АЗС, а для одинакового количества — по названиям улиц в алфавитном порядке.

ExamTaskC52. На вход подаются сведения о ценах на бензин на автозаправочных станциях (АЗС). В первой строке содержится число N, каждая из последующих N строк имеет формат

<Компания> <Улица> <Марка бензина> <Цена 1 литра (в копейках)>

Имеется не более 20 различных компаний и не более 30 различных улиц; названия компаний и улиц не содержат пробелов. В качестве марки бензина указываются числа 92, 95 или 98. Цена задается целым числом в диапазоне от 2000 до 3000. Каждая компания имеет не более одной АЗС на каждой улице; цены на разных АЗС одной и той же компании могут различаться. Для каждой улицы определить количество АЗС, предлагавших определенную марку бензина (вначале выводить название улицы, затем три числа — количество АЗС для бензина марки 92, 95 и 98; некоторые из этих чисел могут быть равны 0). Сведения о каждой улице выводить на новой строке и упорядочивать по названиям улиц в алфавитном порядке.

ExamTaskC53. На вход подаются сведения о ценах на бензин на автозаправочных станциях (АЗС). В первой строке содержится значение M одной из марок бензина, во второй строке указывается целое число N, а каждая из последующих N строк имеет формат

<Марка бензина> <Улица> <Компания> <Цена 1 литра (в копейках)>

Имеется не более 20 различных компаний и не более 30 различных улиц; названия компаний и улиц не содержат пробелов. В качестве марки бензина указываются числа 92, 95 или 98. Цена задается целым числом в диапазоне от 2000 до 3000. Каждая компания имеет не более одной АЗС на каждой улице; цены на разных АЗС одной и той же компании могут различаться. Для каждой улицы, на которой имеются АЗС с бензином марки M, определить максимальную цену бензина этой марки (вначале выводить максимальную цену, затем название улицы). Сведения о каждой улице выводить на новой строке и упорядочивать по возрастанию максимальной цены, а для одинаковой цены — по названиям улиц в алфавитном порядке. Если ни одной АЗС с бензином марки M не найдено, то вывести текст «Нет».

ExamTaskC54. На вход подаются сведения о ценах на бензин на автозаправочных станциях (АЗС). В первой строке содержится число N, каждая из последующих N строк имеет формат

<Марка бензина> <Компания> <Улица> <Цена 1 литра (в копейках)>

Имеется не более 20 различных компаний и не более 30 различных улиц; названия компаний и улиц не содержат пробелов. В качестве марки бензина указываются числа 92, 95 или 98. Цена задается целым числом в диапазоне от 2000 до 3000. Каждая компания имеет не более одной АЗС на каждой улице; цены на разных АЗС одной и той же компании могут различаться. Для каждой улицы определить минимальную цену бензина каждой марки (вначале выводить название улицы, затем три числа — минимальную цену для бензина марки 92, 95 и 98). При отсутствии бензина нужной марки выводить число 0. Сведения о каждой улице выводить на новой строке и упорядочивать по названиям улиц в алфавитном порядке.

ExamTaskC55. На вход подаются сведения о ценах на бензин на автозаправочных станциях (АЗС). В первой строке содержится значение M одной из марок бензина, во второй строке указывается целое число N, а каждая из последующих N строк имеет формат

<Цена 1 литра (в копейках)> <Марка бензина> <Улица> <Компания>

Имеется не более 20 различных компаний и не более 30 различных улиц; названия компаний и улиц не содержат пробелов. В качестве марки бензина указываются числа 92, 95 или 98. Цена задается целым числом в диапазоне от 2000 до 3000. Каждая компания имеет не более одной АЗС на каждой улице; цены на разных АЗС одной и той же компании могут различаться. Для каждой компании определить разброс цен на бензин указанной марки M (вначале выводить разность максимальной и минимальной цены бензина марки M для АЗС данной компании, затем — название компании). Если бензин марки M не предлагался данной компанией, то разброс положить равным −1. Сведения о каждой компании выводить на новой строке, данные упорядочивать по убыванию значений разброса, а для равных значений разброса — по названиям компаний в алфавитном порядке.

ExamTaskC56. На вход подаются сведения о ценах на бензин на автозаправочных станциях (АЗС). В первой строке содержится число N, каждая из последующих N строк имеет формат

<Марка бензина> <Цена 1 литра (в копейках)> <Компания> <Улица>

Имеется не более 20 различных компаний и не более 30 различных улиц; названия компаний и улиц не содержат пробелов. В качестве марки бензина указываются числа 92, 95 или 98. Цена задается целым числом в диапазоне от 2000 до 3000. Каждая компания имеет не более одной АЗС на каждой улице; цены на разных АЗС одной и той же компании могут различаться. Для каждой компании определить разброс цен для всех марок бензина (вначале выводить название компании, затем три числа — разброс цен для бензина марки 92, 95 и 98). При отсутствии бензина нужной марки выводить число −1. Сведения о каждой компании выводить на новой строке и упорядочивать по названиям компаний в алфавитном порядке.

ExamTaskC57. На вход подаются сведения о ценах на бензин на автозаправочных станциях (АЗС). В первой строке содержится число N, каждая из последующих N строк имеет формат

<Компания> <Цена 1 литра (в копейках)> <Марка бензина> <Улица>

Имеется не более 20 различных компаний и не более 30 различных улиц; названия компаний и улиц не содержат пробелов. В качестве марки бензина указываются числа 92, 95 или 98. Цена задается целым числом в диапазоне от 2000 до 3000. Каждая компания имеет не более одной АЗС на каждой улице; цены на разных АЗС одной и той же компании могут различаться. Для каждой улицы определить количество АЗС (вначале выводить название улицы, затем количество АЗС). Сведения о каждой улице выводить на новой строке и упорядочивать по названиям улиц в алфавитном порядке.

ExamTaskC58. На вход подаются сведения о ценах на бензин на автозаправочных станциях (АЗС). В первой строке содержится число N, каждая из последующих N строк имеет формат

<Улица> <Марка бензина> <Цена 1 литра (в копейках)> <Компания>

Имеется не более 20 различных компаний и не более 30 различных улиц; названия компаний и улиц не содержат пробелов. В качестве марки бензина указываются числа 92, 95 или 98. Цена задается целым числом в диапазоне от 2000 до 3000. Каждая компания имеет не более одной АЗС на каждой улице; цены на разных АЗС одной и той же компании могут различаться. Для каждой компании определить количество АЗС (вначале выводить количество АЗС, затем — название компании). Сведения о каждой компании выводить на новой строке и упорядочивать по убыванию количества АЗС, а при равных количествах — по названиям компаний в алфавитном порядке.

ExamTaskC59. На вход подаются сведения о ценах на бензин на автозаправочных станциях (АЗС). В первой строке содержится число N, каждая из последующих N строк имеет формат

<Цена 1 литра (в копейках)> <Улица> <Марка бензина> <Компания>

Имеется не более 20 различных компаний и не более 30 различных улиц; названия компаний и улиц не содержат пробелов. В качестве марки бензина указываются числа 92, 95 или 98. Цена задается целым числом в диапазоне от 2000 до 3000. Каждая компания имеет не более одной АЗС на каждой улице; цены на разных АЗС одной и той же компании могут различаться. Вывести данные обо всех АЗС, предлагавших все три марки бензина (вначале выводится название улицы, затем название компании). Сведения о каждой АЗС выводить на новой строке и упорядочивать по названиям улиц в алфавитном порядке, а для одинаковых названий улиц — по названиям компаний (также в алфавитном порядке). Если ни одной требуемой АЗС не найдено, то вывести текст «Нет».

ExamTaskC60. На вход подаются сведения о ценах на бензин на автозаправочных станциях (АЗС). В первой строке содержится число N, каждая из последующих N строк имеет формат

<Цена 1 литра (в копейках)> <Компания> <Улица> <Марка бензина>

Имеется не более 20 различных компаний и не более 30 различных улиц; названия компаний и улиц не содержат пробелов. В качестве марки бензина указываются числа 92, 95 или 98. Цена задается целым числом в диапазоне от 2000 до 3000. Каждая компания имеет не более одной АЗС на каждой улице; цены на разных АЗС одной и той же компании могут различаться. Вывести данные обо всех АЗС, предлагавших не менее двух марок бензина (вначале выводится название компании, затем название улицы, затем количество предлагавшихся марок бензина). Сведения о каждой АЗС выводить на новой строке и упорядочивать по названиям компаний в алфавитном порядке, а для одинаковых компаний — по названиям улиц (также в алфавитном порядке). Если ни одной требуемой АЗС не найдено, то вывести текст «Нет».

ExamTaskC61. На вход подаются сведения о сдаче ЕГЭ по математике, русскому языку и информатике (в указанном порядке). В первой строке указывается количество учащихся N, каждая из последующих N строк имеет формат

<Фамилия> <Инициалы> <Номер школы> <Баллы ЕГЭ>

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

ExamTaskC62. На вход подаются сведения о сдаче ЕГЭ по математике, русскому языку и информатике (в указанном порядке). В первой строке указывается количество учащихся N, каждая из последующих N строк имеет формат

<Фамилия> <Инициалы> <Баллы ЕГЭ> <Номер школы>

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

ExamTaskC63. На вход подаются сведения о сдаче ЕГЭ по математике, русскому языку и информатике (в указанном порядке). В первой строке указывается количество учащихся N, каждая из последующих N строк имеет формат

<Баллы ЕГЭ> <Фамилия> <Инициалы> <Номер школы>

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

ExamTaskC64. На вход подаются сведения о сдаче ЕГЭ по математике, русскому языку и информатике (в указанном порядке). В первой строке указывается количество учащихся N, каждая из последующих N строк имеет формат

<Номер школы> <Фамилия> <Инициалы> <Баллы ЕГЭ>

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

ExamTaskC65. На вход подаются сведения о сдаче ЕГЭ по математике, русскому языку и информатике (в указанном порядке). В первой строке указывается количество учащихся N, каждая из последующих N строк имеет формат

<Номер школы> <Баллы ЕГЭ> <Фамилия> <Инициалы>

Количество учащихся не превосходит 100. Номер школы содержит не более двух цифр, баллы ЕГЭ представляют собой три целых числа в диапазоне от 0 до 100, которые отделяются друг от друга одним пробелом. Для каждой школы, присутствующей в наборе исходных данных, и каждого предмета определить количество учащихся, набравших не менее 50 баллов по этому предмету (вначале выводится номер школы, затем три числа — количество учащихся этой школы, набравших требуемое число баллов по математике, русскому языку и информатике; некоторые из чисел могут быть равны 0). Сведения о каждой школе выводить на новой строке и упорядочивать по возрастанию номера школы.

ExamTaskC66. На вход подаются сведения о сдаче ЕГЭ по математике, русскому языку и информатике (в указанном порядке). В первой строке указывается количество учащихся N, каждая из последующих N строк имеет формат

<Фамилия> <Инициалы> <Номер школы> <Баллы ЕГЭ>

Количество учащихся не превосходит 100. Номер школы содержит не более двух цифр, баллы ЕГЭ представляют собой три целых числа в диапазоне от 0 до 100, которые отделяются друг от друга одним пробелом. Для каждой школы, присутствующей в наборе исходных данных, определить количество учащихся, суммарный балл которых превышает 150 баллов (вначале выводится количество учащихся, набравших в сумме более 150 баллов, затем номер школы; количество учащихся может быть равно 0). Сведения о каждой школе выводить на новой строке и упорядочивать по убыванию количества учащихся, а для одинакового количества — по возрастанию номера школы.

ExamTaskC67. На вход подаются сведения о сдаче ЕГЭ по математике, русскому языку и информатике (в указанном порядке). В первой строке указывается количество учащихся N, каждая из последующих N строк имеет формат

<Фамилия> <Инициалы> <Баллы ЕГЭ> <Номер школы>

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

ExamTaskC68. На вход подаются сведения о сдаче ЕГЭ по математике, русскому языку и информатике (в указанном порядке). В первой строке указывается количество учащихся N, каждая из последующих N строк имеет формат

<Баллы ЕГЭ> <Номер школы> <Фамилия> <Инициалы>

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

ExamTaskC69. На вход подаются сведения о сдаче ЕГЭ по математике, русскому языку и информатике (в указанном порядке). В первой строке указывается количество учащихся N, каждая из последующих N строк имеет формат

<Номер школы> <Фамилия> <Инициалы> <Баллы ЕГЭ>

Количество учащихся не превосходит 100. Номер школы содержит не более двух цифр, баллы ЕГЭ представляют собой три целых числа в диапазоне от 0 до 100, которые отделяются друг от друга одним пробелом. Вывести сведения об учащихся, набравших менее 50 баллов по каждому предмету (вначале выводится номер школы, затем фамилия, инициалы и суммарный балл ЕГЭ по всем предметам). Сведения о каждом учащемся выводить на отдельной строке и упорядочивать по возрастанию номера школы, а для совпадающих номеров — в порядке следования учащихся в наборе исходных данных. Если ни один из учащихся не удовлетворяет указанным условиям, то вывести текст «Требуемые учащиеся не найдены».

ExamTaskC70. На вход подаются сведения о сдаче ЕГЭ по математике, русскому языку и информатике (в указанном порядке). В первой строке указывается количество учащихся N, каждая из последующих N строк имеет формат

<Баллы ЕГЭ> <Фамилия> <Инициалы> <Номер школы>

Количество учащихся не превосходит 100. Номер школы содержит не более двух цифр, баллы ЕГЭ представляют собой три целых числа в диапазоне от 0 до 100, которые отделяются друг от друга одним пробелом. Вывести сведения об учащихся, набравших не менее 50 баллов по каждому предмету (вначале выводится фамилия и инициалы, затем номер школы и суммарный балл ЕГЭ по всем предметам). Сведения о каждом учащемся выводить на отдельной строке в алфавитном порядке фамилий и инициалов, а при их совпадении — в порядке следования учащихся в наборе исходных данных. Если ни один из учащихся не удовлетворяет указанным условиям, то вывести текст «Требуемые учащиеся не найдены».

ExamTaskC71. На вход подаются сведения о сдаче ЕГЭ по математике, русскому языку и информатике (в указанном порядке). В первой строке указывается количество учащихся N, каждая из последующих N строк имеет формат

<Фамилия> <Инициалы> <Номер школы> <Баллы ЕГЭ>

Количество учащихся не превосходит 100. Номер школы содержит не более двух цифр, баллы ЕГЭ представляют собой три целых числа в диапазоне от 0 до 100, которые отделяются друг от друга одним пробелом. Вывести сведения об учащихся, набравших менее 10 баллов хотя бы по одному из предметов (вначале выводится номер школы, затем фамилия и инициалы). Сведения о каждом учащемся выводить на отдельной строке и располагать по убыванию номера школы, а для совпадающих номеров — в алфавитном порядке фамилий и инициалов. Если ни один из учащихся не удовлетворяет указанным условиям, то вывести текст «Требуемые учащиеся не найдены».

ExamTaskC72. На вход подаются сведения о сдаче ЕГЭ по математике, русскому языку и информатике (в указанном порядке). В первой строке указывается количество учащихся N, каждая из последующих N строк имеет формат

<Фамилия> <Инициалы> <Баллы ЕГЭ> <Номер школы>

Количество учащихся не превосходит 100. Номер школы содержит не более двух цифр, баллы ЕГЭ представляют собой три целых числа в диапазоне от 0 до 100, которые отделяются друг от друга одним пробелом. Вывести сведения об учащихся, набравших более 90 баллов хотя бы по одному из предметов (вначале выводится фамилия и инициалы, затем номер школы). Сведения о каждом учащемся выводить на отдельной строке и располагать в алфавитном порядке фамилий и инициалов, а при их совпадении — по возрастанию номера школы. Если ни один из учащихся не удовлетворяет указанным условиям, то вывести текст «Требуемые учащиеся не найдены».

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

<Фамилия> <Инициалы> <Класс> <Название предмета> <Оценка>

Количество учащихся не превосходит 100, полных однофамильцев (с совпадающей фамилией и инициалами) среди учащихся нет. Класс описывается целым числом в диапазоне от 7 до 11, оценка — целым числом в диапазоне от 2 до 5. Название предмета указывается с заглавной буквы. Для каждого учащегося определить среднюю оценку по каждому предмету и вывести ее с двумя дробными знаками (если по какому-либо предмету учащийся не получил ни одной оценки, то вывести для этого предмета 0.00). Сведения о каждом учащемся выводить на отдельной строке, указывая фамилию, инициалы и средние оценки по алгебре, геометрии и информатике. Данные располагать в алфавитном порядке фамилий и инициалов.

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

<Класс> <Фамилия> <Инициалы> <Оценка> <Название предмета>

Количество учащихся не превосходит 100, полных однофамильцев (с совпадающей фамилией и инициалами) среди учащихся нет. Класс описывается целым числом в диапазоне от 7 до 11, оценка — целым числом в диапазоне от 2 до 5. Название предмета указывается с заглавной буквы. Для каждого учащегося определить количество оценок по каждому предмету (если по какому-либо предмету учащийся не получил ни одной оценки, то вывести для этого предмета число 0). Сведения о каждом учащемся выводить на отдельной строке, указывая класс, фамилию, инициалы и количество оценок по алгебре, геометрии и информатике. Данные располагать в порядке возрастания номера класса, а для одинаковых классов — в алфавитном порядке фамилий и инициалов.

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

<Название предмета> <Фамилия> <Инициалы> <Класс> <Оценка>

Количество учащихся не превосходит 100, полных однофамильцев (с совпадающей фамилией и инициалами) среди учащихся нет. Класс описывается целым числом в диапазоне от 7 до 11, оценка — целым числом в диапазоне от 2 до 5. Название предмета указывается с заглавной буквы. Вывести сведения об учащихся, имеющих по алгебре среднюю оценку не более 4.0: фамилию, инициалы, номер класса и среднюю оценку по алгебре (выводится с двумя дробными знаками). Учащихся, не имеющих ни одной оценки по алгебре, не учитывать. Сведения о каждом учащемся выводить на отдельной строке и располагать в алфавитном порядке их фамилий и инициалов. Если ни один из учащихся не удовлетворяет указанным условиям, то вывести текст «Требуемые учащиеся не найдены».

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

<Класс> <Фамилия> <Инициалы> <Название предмета> <Оценка>

Количество учащихся не превосходит 100, полных однофамильцев (с совпадающей фамилией и инициалами) среди учащихся нет. Класс описывается целым числом в диапазоне от 7 до 11, оценка — целым числом в диапазоне от 2 до 5. Название предмета указывается с заглавной буквы. Вывести сведения об учащихся, имеющих по информатике среднюю оценку не менее 4.0: номер класса, фамилию, инициалы и среднюю оценку по информатике (выводится с двумя дробными знаками). Сведения о каждом учащемся выводить на отдельной строке и располагать в порядке возрастания классов, а для одинаковых классов — в алфавитном порядке фамилий и инициалов. Если ни один из учащихся не удовлетворяет указанным условиям, то вывести текст «Требуемые учащиеся не найдены».

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

<Фамилия> <Инициалы> <Название предмета> <Оценка> <Класс>

Количество учащихся не превосходит 100, полных однофамильцев (с совпадающей фамилией и инициалами) среди учащихся нет. Класс описывается целым числом в диапазоне от 7 до 11, оценка — целым числом в диапазоне от 2 до 5. Название предмета указывается с заглавной буквы. Для каждого класса, присутствующего в наборе исходных данных, определить число учащихся, имеющих по предмету S среднюю оценку не более 3.5. Учащихся, не имеющих ни одной оценки по данному предмету, не учитывать. Сведения о каждом классе выводить на отдельной строке, указывая число найденных учащихся (число может быть равно 0) и номер класса. Данные упорядочивать по возрастанию числа учащихся, а для совпадающих чисел — по убыванию номера класса.

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

<Название предмета> <Фамилия> <Инициалы> <Оценка> <Класс>

Количество учащихся не превосходит 100, полных однофамильцев (с совпадающей фамилией и инициалами) среди учащихся нет. Класс описывается целым числом в диапазоне от 7 до 11, оценка — целым числом в диапазоне от 2 до 5. Название предмета указывается с заглавной буквы. Для каждого класса, присутствующего в наборе исходных данных, определить число учащихся, имеющих по предмету S среднюю оценку не менее 3.5 и при этом не получивших ни одной двойки по этому предмету. Сведения о каждом классе выводить на отдельной строке, указывая номер класса и число найденных учащихся (число может быть равно 0). Данные упорядочивать по возрастанию номера класса.

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

<Класс> <Название предмета> <Фамилия> <Инициалы> <Оценка>

Количество учащихся не превосходит 100, полных однофамильцев (с совпадающей фамилией и инициалами) среди учащихся нет. Класс описывается целым числом в диапазоне от 7 до 11, оценка — целым числом в диапазоне от 2 до 5. Название предмета указывается с заглавной буквы. Найти всех двоечников — учащихся, получивших хотя бы одну двойку по какому-либо предмету. Вывести сведения о каждом из двоечников: номер класса, фамилию, инициалы и полученное число двоек. Сведения о каждом двоечнике выводить на отдельной строке и располагать по убыванию классов, а для одинаковых классов — в алфавитном порядке фамилий и инициалов. Если в наборе исходных данных нет ни одной двойки, то вывести текст «Требуемые учащиеся не найдены».

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

<Класс> <Оценка> <Фамилия> <Инициалы> <Название предмета>

Количество учащихся не превосходит 100, полных однофамильцев (с совпадающей фамилией и инициалами) среди учащихся нет. Класс описывается целым числом в диапазоне от 7 до 11, оценка — целым числом в диапазоне от 2 до 5. Название предмета указывается с заглавной буквы. Найти всех хорошистов — учащихся, не получивших ни одной двойки и тройки, но имеющих хотя бы одну четверку по какому-либо предмету. Вывести сведения о каждом хорошисте: полученное число четверок, фамилию, инициалы и номер класса. Сведения о каждом учащемся выводить на отдельной строке и располагать по возрастанию количества четверок, а при их равенстве — в алфавитном порядке фамилий и инициалов. Если в наборе исходных данных нет ни одного учащегося, удовлетворяющего указанным условиям, то вывести текст «Требуемые учащиеся не найдены».

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

<Класс> <Фамилия> <Инициалы> <Название предмета> <Оценка>

Количество учащихся не превосходит 100, полных однофамильцев (с совпадающей фамилией и инициалами) среди учащихся нет. Класс описывается целым числом в диапазоне от 7 до 11, оценка — целым числом в диапазоне от 2 до 5. Название предмета указывается с заглавной буквы. Для каждого класса найти злостных двоечников — учащихся, получивших в данном классе максимальное суммарное число двоек по всем предметам (число не должно быть нулевым). Вывести сведения о каждом из злостных двоечников: фамилию, инициалы, номер класса и полученное число двоек. Сведения о каждом двоечнике выводить на отдельной строке и располагать в алфавитном порядке их фамилий и инициалов (сортировку по классам не проводить). Если в наборе исходных данных нет ни одной двойки, то вывести текст «Требуемые учащиеся не найдены».

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

<Оценка> <Класс> <Фамилия> <Инициалы> <Название предмета>

Количество учащихся не превосходит 100, полных однофамильцев (с совпадающей фамилией и инициалами) среди учащихся нет. Класс описывается целым числом в диапазоне от 7 до 11, оценка — целым числом в диапазоне от 2 до 5. Название предмета указывается с заглавной буквы. Для каждого класса найти лучших учеников — учащихся, получивших в данном классе максимальное суммарное число пятерок по всем предметам (число не должно быть нулевым). При поиске лучших учеников (в частности, при определении максимального суммарного числа пятерок) не следует учитывать учащихся, получивших хотя бы одну двойку или тройку. Вывести сведения о каждом из лучших учеников: номер класса, фамилию, инициалы и полученное число пятерок. Сведения о каждом учащемся выводить на отдельной строке и располагать по возрастанию классов, а для одинаковых классов — в алфавитном порядке фамилий и инициалов. Если в наборе исходных данных нет ни одного учащегося, удовлетворяющего указанным условиям, то вывести текст «Требуемые учащиеся не найдены».

Обработка текстовых данных

ExamTaskC83. На вход подается набор символов, оканчивающийся точкой. Количество символов не превышает 200. Найти и вывести сумму цифр, входящих в исходный набор. Если набор не содержит цифр, то вывести слово «NO».

ExamTaskC84. На вход подается набор символов, оканчивающийся точкой. Количество символов не превышает 200. Найти сумму чисел, входящих в исходный набор (число образуют подряд идущие цифры; известно, что сумма чисел не превосходит 20000). Если исходный набор не содержит цифр, то вывести число −1.

ExamTaskC85. На вход подается набор символов, оканчивающийся точкой. Количество символов не превышает 200. Подряд идущие в наборе цифры образуют одно число; известно, что все числа имеют не более 4 разрядов (незначащие нули при подсчете количества разрядов не учитываются). Найти общую сумму всех однозначных и двузначных чисел и общее количество всех трехзначных и четырехзначных чисел. Вывести два полученных числа в одной строке в указанном порядке, разделяя их одним пробелом. Если набор не содержит чисел с требуемым количеством разрядов, то в качестве соответствующего числа вывести 0.

ExamTaskC86. На вход подается набор символов, оканчивающийся точкой. Количество символов не превышает 200. Составить из имеющихся в наборе нечетных цифр минимальное число и вывести строковое представления этого числа. Каждая цифра должна использоваться столько раз, сколько раз она встречается в исходном наборе. Если в наборе нет нечетных цифр, то вывести слово «NO».

ExamTaskC87. На вход подается набор символов, оканчивающийся точкой. Количество символов не превышает 200. Составить из имеющихся в наборе четных цифр максимальное число и вывести строковое представление этого числа. Каждая цифра должна использоваться столько раз, сколько раз она встречается в исходном наборе (за исключением ситуации, когда отсутствуют все четные цифры, кроме цифры 0; в этом случае надо вывести строку «0»). Если в наборе нет четных цифр, то вывести слово «NO».

ExamTaskC88. На вход подается набор символов, оканчивающийся точкой. Количество символов не превышает 200; в наборе обязательно присутствуют цифры. Составить из имеющихся цифр максимальное число, которое читается одинаково как слева направо, так и справа налево. Все цифры можно не использовать; незначащих нулей в числе не должно быть. Вывести строку, изображающую найденное число.

ExamTaskC89. На вход подается набор символов, оканчивающийся точкой. Количество символов не превышает 200. Составить из имеющихся в тексте нечетных цифр число максимальной длины, которое читается одинаково как слева направо, так и справа налево. Все цифры можно не использовать. Если требуемое число составить нельзя, то вывести слово «NO»; если можно, то в первой строке вывести слово «YES», а во второй — строку, изображающую найденное число. Если таких чисел несколько, то вывести минимальное из них.

ExamTaskC90. На вход подается набор символов, оканчивающийся точкой. Количество символов не превышает 200. Составить из имеющихся в тексте четных цифр максимальное число, которое читается одинаково как слева направо, так и справа налево. Все цифры можно не использовать; незначащих нулей в числе не должно быть. Если требуемое число составить нельзя, то вывести слово «NO»; если можно, то в первой строке вывести слово «YES», а во второй — строку, изображающую найденное число.

ExamTaskC91. На вход в первой строке подается целое положительное число N, затем следует текст на английском языке, состоящий из N строк. В каждой строке текста содержится не более 80 символов. Зашифровать исходный текст и вывести его зашифрованный вариант. Шифрование заключается в замене каждой латинской буквы на букву, симметричную шифруемой букве относительно середины английского алфавита (например, «a» должна заменяться на «z», «b» на «y», «x» на «c»). Регистр букв при шифровании остается прежним. Если символ не является латинской буквой, то он не изменяется.

ExamTaskC92. На вход в первой строке подаются два целых положительных числа: K и N, причем K не превосходит 25. Затем следует текст на английском языке, состоящий из N строк. В каждой строке текста содержится не более 80 символов. Зашифровать исходный текст и вывести его зашифрованный вариант. Шифрование заключается в замене каждой латинской буквы на букву, расположенную в алфавите на K-й позиции после шифруемой буквы (алфавит считается циклическим: за буквой «z» опять следует буква «a»). Регистр букв при шифровании остается прежним. Если символ не является латинской буквой, то он не изменяется.

ExamTaskC93. На вход в первой строке подается символ C — латинская буква, во второй строке — целое положительное число N. Затем следует зашифрованный текст на английском языке, состоящий из N строк. В каждой строке текста содержится не более 80 символов. Известно, что шифрование выполнялось по тем же правилам, что и в задании ExamTaskC92, причем первый зашифрованный символ текста должен после расшифровки стать символом С. Расшифровать исходный текст и вывести его расшифрованный вариант. Первый зашифрованный символ не обязательно является первым символом текста (поскольку в начале текста может располагаться цифра или знак препинания), однако можно считать, что он всегда присутствует в первой строке текста.

ExamTaskC94. На вход в первой строке подается целое положительное число N, затем следует текст на английском языке, состоящий из N строк. В каждой строке текста содержится не более 80 символов. Зашифровать исходный текст и вывести его зашифрованный вариант. Шифрование заключается в следующем: каждая латинская буква в слове из L букв заменяется на букву, расположенную в алфавите на L-й позиции после шифруемой буквы (алфавит считается циклическим: за буквой «z» опять следует буква «a»). Например, текст «A gray box.» должен быть заменен на «B kvec era.». Регистр букв при шифровании остается прежним. Словом считается последовательность латинских букв, не содержащая пробелов и знаков препинания. Если символ не является латинской буквой, то он не изменяется.

ExamTaskC95. На вход в первой строке подаются два целых положительных числа: K и N, причем K не превосходит 10. Затем следует текст на английском языке, состоящий из N строк. В каждой строке текста содержится не более 80 символов. Зашифровать исходный текст и вывести его зашифрованный вариант. Шифрование заключается в следующем: каждая латинская буква в слове из L букв заменяется на букву, расположенную в алфавите на (K + L)-й позиции после шифруемой буквы (алфавит считается циклическим: за буквой «z» опять следует буква «a»). Например, текст «A gray box.» при K = 1 должен быть заменен на «C lwfd fsb.». Регистр букв при шифровании остается прежним. Словом считается последовательность латинских букв, не содержащая пробелов и знаков препинания. Если символ не является латинской буквой, то он не изменяется.

ExamTaskC96. На вход в первой строке подается символ C — латинская буква, во второй строке — целое положительное число N. Затем следует зашифрованный текст на английском языке, состоящий из N строк. В каждой строке текста содержится не более 80 символов. Известно, что шифрование выполнялось по тем же правилам, что и в задании ExamTaskC95, причем первый зашифрованный символ текста должен после расшифровки стать символом С. Расшифровать исходный текст и вывести его расшифрованный вариант. Первый зашифрованный символ не обязательно является первым символом текста (поскольку в начале текста может располагаться цифра или знак препинания), однако можно считать, что он всегда присутствует в первой строке текста.

ExamTaskC97. На вход в первой строке подается целое положительное число N, затем следует текст на английском языке, состоящий из N строк. В каждой строке текста содержится не более 80 символов. Вывести все символы, встретившиеся в исходном тексте, включая пробел и знаки препинания (без повторений). Символы выводить в одной строке (без разделителей) в порядке их первого появления в тексте.

ExamTaskC98. На вход в первой строке подается целое положительное число N, затем следует текст на английском языке, состоящий из N строк. В каждой строке текста содержится не более 80 символов. Вывести все символы, встретившиеся в исходном тексте, включая пробел и знаки препинания (без повторений). Символы выводить в одной строке (без разделителей) в порядке возрастания их кодов.

ExamTaskC99. На вход в первой строке подается целое положительное число N, затем следует текст на английском языке, состоящий из N строк. В каждой строке текста содержится не более 80 символов. Вывести последовательность строчных латинских букв (a, b, c, …, z) из исходного текста и число их повторений в этом тексте. Вывод производится в алфавитном порядке, каждая буква выводится на новой строке, после буквы указывается пробел и число ее повторений в тексте. Буквы, отсутствующие в тексте, не выводить.

ExamTaskC100. На вход в первой строке подается целое положительное число N, затем следует текст на английском языке, состоящий из N строк. В каждой строке текста содержится не более 80 символов; в тексте встречается не менее 10 различных строчных латинских букв. Найти 10 строчных латинских букв, повторяющихся в тексте чаще всего. Для каждой буквы вывести число ее повторений в тексте, и, через пробел, саму эту букву. Сведения о каждой букве выводятся на отдельной строке и располагаются в порядке убывания числа повторений букв в тексте, а при одинаковом числе повторений — в алфавитном порядке букв. Если имеются другие буквы, число повторений которых равно числу повторений последней из 10 найденных букв, то сведения о них тоже следует вывести.


Указания

[Перейти к предисловию] [Перейти к началу раздела «Группы заданий»] [Перейти к списку литературы]

В данном разделе дается общий обзор каждой группы заданий, приведенной в первом разделе, рассматриваются особенности заданий, входящих в эти группы, и даются методические рекомендации по организации практических занятий, посвященных соответствующей теме. Для каждой группы заданий (а в случае группы заданий большого размера — и для каждой ее подгруппы) приводится список заданий, которые рекомендуется рассмотреть на занятиях («Разбор в классе»), и список заданий для самостоятельного выполнения («Закрепление материала»). Кроме того, отмечены задания, имеющий уровень ниже среднего («Простые задания») и выше среднего («Сложные задания»; задания повышенной сложности помечены звездочкой). Указываются также наборы однотипных заданий, которые удобно использовать при составлении вариантов индивидуальных заданий.

Все упоминания конкретных задач снабжены гиперссылками, позволяющими сразу перейти к формулировке упомянутой задачи, приведенной в первом разделе пособия. При указании диапазонов номеров задач имеется возможность перейти как к начальной, так и к конечной задаче из указанного диапазона. При упоминании задач группы Dynamic и Tree, представленных в пособии в двух вариантах, используется ссылка вида <номер>[net] (например, 1[net]); щелчок мышью на номере обеспечивает переход к формулировке задачи, ориентированной на использование указателей, щелчок на тексте «net» — переход к варианту формулировки для платформы .NET, ориентированной на использование объектов.

Приведенные ниже ссылки позволяют сразу перейти к указаниям, связанным с требуемой группой заданий.

  • Begin, Integer, Boolean
  • If, Case, For, While
  • Proc
  • Series, Minmax
  • Array
  • Matrix
  • String
  • File
  • Text
  • Param
  • Recur
  • Dynamic
  • Tree
  • ExamBegin, ExamTaskC


Указания

Ввод и вывод данных, оператор присваивания: группа Begin

[Перейти к формулировкам] [Перейти к началу раздела «Группы заданий»] [Перейти к началу раздела «Указания»]

Группа Begin является первой из групп начального уровня; она предназначена для ознакомления с процедурами ввода-вывода и оператором присваивания. В качестве исходных и результирующих данных во всех заданиях используются данные вещественного типа.

Первые задания из данной группы (1–9) не предполагают использование оператора присваивания. Главное в них — описание переменных и ввод-вывод данных, а также использование арифметических операций и простейших функций (в частности, функции извлечения квадратного корня). В качестве примера укажем задание 3 (о нахождении площади и периметра прямоугольника по его сторонам), которое подробно разбирается в пособиях [1, 5, 10]. Уже в заданиях 10–11 использование оператора присваивания является оправданным (например, в задании 10 требуется вычислить несколько выражений, содержащих квадраты исходных данных; в этой ситуации разумно завести вспомогательные переменные для всех требуемых квадратов). В группе таких заданий (10–28) следует особо выделить задачи, связанные с определением расстояния на прямой (16–18) и на плоскости (19–21), требующие использования функции модуль. Принципиальную важность имеют задания, связанные с переменой местами содержимого двух (или трех) переменных: 22–24. Полезно проанализировать также одно из заданий 27–28, в которых идет речь об эффективном вычислении степени данного числа (с применением минимального количества арифметических операций).

Все прочие задания данной группы (29–40) служат для закрепления материала; они отличаются только «предметной областью» (например, задания 35–37 имеют «физическое» содержание). В этих заданиях полезно особое внимание уделить организации наглядного ввода и вывода (при условии, что на занятиях не используется электронный задачник Programming Taskbook, который автоматически обеспечивает наглядный ввод-вывод данных).

Группа: Begin
Разбор в классе: 3, 9, 10, 13, 17, 22, 27
Закрепление материала: 4, 7, 8, 11, 14, 18, 23, 28
Простые задания: 1, 2, 8, 16
Сложные задания: 19, 21, 39, 40
Наборы однотипных заданий: 1–7; 8–9; 10–11; 13–15; 16–18; 23–24; 25–26; 29–32; 35–37

Целые числа: группа Integer

[Перейти к формулировкам] [Перейти к началу раздела «Группы заданий»] [Перейти к началу раздела «Указания»]

Основная цель заданий этой группы — познакомиться с особыми операциями целочисленного деления и узнать, в каких ситуациях их следует использовать. В этой группе заданий впервые вводится целочисленный тип данных.

Задания 1–5 являются вводными; в их формулировках явно говорится, какую из операций, связанных с целочисленным делением, надо использовать. Затем идет серия заданий на выделение цифр из многозначных целых чисел и на их перестановку. Рассматриваются двузначные (6–8), трехзначные (9–16) и многозначные (17–18) числа.

Два других аспекта применения целочисленных операций иллюстрируются группами задач 19–23 и 24–28. Первая группа посвящена задачам выделения различных промежутков времени, связанных с указанным количеством секунд, прошедших с начала суток (определить количество полных часов, минут, секунд с начала последнего часа или с начала последней минуты и т. д.). Вторая группа посвящена определению дня недели для дня года с указанным номером, если дан день недели для 1 января и используется один из возможных вариантов нумерации дней недели (от 0 или от 1).

Следует также обратить внимание на задачу 29 (определение количества квадратов, которые можно разместить на данном прямоугольнике), поскольку, учащиеся, как правило, вначале предлагают неверный алгоритм ее решения: разделить площадь прямоугольника на площадь квадрата.

Группа: Integer
Разбор в классе: 4, 5, 6, 8, 9, 17, 20, 24, 29
Закрепление материала: 1, 3, 12, 13, 18, 21, 25, 26
Простые задания: 1, 2, 3, 7, 11, 19,
Сложные задания: 23, 27, 28, 29, 30
Наборы однотипных заданий: 1–5; 6–8; 9–16; 17–18; 19–23; 24–28

Логические выражения: группа Boolean

[Перейти к формулировкам] [Перейти к началу раздела «Группы заданий»] [Перейти к началу раздела «Указания»]

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

Во всех заданиях группы Boolean требуется вывести логическое значение, соответствующее истинности некоторого утверждения, в которое входят введенные данные, например, проверить истинность утверждения «Целое число A является положительным» (задание 1). Важно отметить, что для решения таких задач не требуется использовать условный оператор, так как достаточно вывести на экран значение соответствующего логического выражения.

Первые семь заданий знакомят с операциями отношения и логическими операциями, а также с проверкой числа на четность/нечетность (задания 2–3) и анализом двойных неравенств вида A < B < C (задание 6). Следует обратить внимание на задание 7, в котором требуется проверить, что некоторое число лежит между двумя другими; желательно рассмотреть несколько вариантов его решения.

Задания 8–11 и 12–15 образуют две серии заданий на комбинацию логических операций. Задания 20–23 требуют анализа цифр данного числа, поэтому при их выполнении необходимо пользоваться знаниями, полученными при выполнении заданий группы Integer. Задания 25–33 имеют геометрическое содержание: в 25–29 речь идет о координатах на плоскости, а в 30–33 — об определении типа треугольника по длинам его сторон. Последняя группа заданий (34–40) имеет «шахматное» содержание: в первых двух требуется проанализировать цвет одной или двух данных клеток, а в остальных требуется определить, может ли определенная шахматная фигура за один ход перейти с одной данной клетки на другую. Наибольший интерес здесь представляют задачи, связанные с ходом слона и коня, которые рекомендуется обсудить в классе.

Группа: Boolean
Разбор в классе: 2, 6, 7, 8, 16, 21, 27, 29, 32, 34, 38, 40
Закрепление материала: 3, 4, 9, 10, 17, 22, 28, 33, 35, 37, 39
Простые задания: 1, 2, 3, 4, 5, 24, 25, 26, 30, 31
Сложные задания: 12, 13, 14, 15, 23, 29, 33, 37, 38, 40
Наборы однотипных заданий: 2–3; 4–6; 8–11; 12–15; 17–18; 19–23; 25–28; 30–33; 36–40


Указания

Условный оператор: группа If

[Перейти к формулировкам] [Перейти к началу раздела «Группы заданий»] [Перейти к началу раздела «Указания»]

Начальные задания (1–5) знакомят с различными вариантами условных операторов (сокращенная и полная форма условного оператора, а также вложенные условные операторы). Следующая большая группа заданий (6–15) связана с нахождением минимальных и максимальных элементов (а также их номеров) в простейших случаях: когда имеется два или три элемента, а также вариациям на эту тему. Отметим также задания на проверку упорядоченности трех чисел (16–17). В группе заданий 18–23 эффективное решение можно получить с помощью вложенных условных операторов; приведем характерное задание из этой группы (номер 22): «определить номер координатной четверти, в которой находится точка с данными ненулевыми координатами». Для подобных заданий полезно проанализировать несколько вариантов их решения. Кроме того, полезно отметить идентичность алгоритмов, применяемых для решения «разных» по формулировке заданий: 19 и 23.

Следующая группа заданий (24–27) посвящена вычислению функций, заданных различными выражениями на разных участках своей области определения. Целесообразно рассмотреть задание 26 для функции, заданной на трех участках, и показать, что количество сравнений для отбора требуемого участка не превосходит n – 1, где n — количество участков.

Задания 27–30 имеют повышенную сложность; в 29–30 дополнительно требуется использовать данные строкового типа и операцию сцепления строк.

Группа: If
Разбор в классе: 1, 2, 3, 7, 9, 12, 19, 21, 26
Закрепление материала: 4, 5, 8, 11, 14, 22, 23, 25
Простые задания: 1, 2, 4, 6, 24
Сложные задания: 13, 15, 23, 27, 28, 29, 30
Наборы однотипных заданий: 1–5; 9–11; 16–17; 18–22; 24–26; 29–30

Оператор выбора: группа Case

[Перейти к формулировкам] [Перейти к началу раздела «Группы заданий»] [Перейти к началу раздела «Указания»]

Во вводных заданиях этой группы (1–5) следует отметить задание 2, в котором естественно возникает вариант «по умолчанию» (else в Pascal и Visual Basic, default в C++ и C#), а также задания 3–4, в которых, в случае использования языков Pascal или Visual Basic, удобно использовать диапазоны значений (например, в задании 3 надо вывести строку с названием времени года для данного месяца, а в задании 4 надо определить число дней в указанном месяце для невисокосного года).

Отметим также задания 8–9, в которых по данному номеру дня и месяца надо определить номер дня и месяца для следующей или предыдущей даты. В этих заданияx приходится совместно использовать оператор выбора и условный оператор.

Задания 15–19 связаны с формированием строковых данных; наиболее сложным из них является 19, в котором надо сформировать словесное описание числа, лежащего в диапазоне 100–999. Эти задания, как и задания 12–14 и 20, являются дополнительными.

Группа: Case
Разбор в классе: 2, 3, 4, 6, 8, 10, 16
Закрепление материала: 5, 7, 9, 11, 15
Простые задания: 1, 2, 5
Сложные задания: 10, 11, 16, 17, 18, 19, 20
Наборы однотипных заданий: 6–7; 8–9; 10–11; 12–14; 15–18

Цикл с параметром: группа For

[Перейти к формулировкам] [Перейти к началу раздела «Группы заданий»] [Перейти к началу раздела «Указания»]

В данной группе содержится много важных алгоритмов, обязательных для твердого усвоения. Следует отметить, что эту группу заданий можно рассмотреть до групп Boolean, If и Case, так как в заданиях группы For условные операторы применять не требуется. Такой подход реализован в пособии [10]; он особенно удобен при изучении языков Pascal и Visual Basic, так как в них конструкции цикла For не требуют использования логических выражений (в частности, операций отношения).

Задания 1–6 являются простейшими заданиями на оператор цикла с параметром. При этом в задании 3 удобно использовать цикл с убывающим параметром, а в заданиях 5 и 6 возникает необходимость в выводе формул, содержащих параметр цикла (например, в задании 6 требуется вывести стоимость 0.1, 0.2, ..., 1 кг конфет, если известна цена 1 кг).

Последующие задания (7–14) посвящены алгоритмам нахождения сумм и произведений при условии, что известно число слагаемых и их вид (например, в задании 10 требуется найти сумму чисел 1 + 1/2 + ... + 1/N для данного N). Закреплению данных алгоритмов служат серии заданий 15–18 и 19–21, первая из которых посвящена операции возведения в степень, а вторая — факториалам.

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

Задания 29–30 знакомят с приемами табулирования с фиксированным шагом значений функции на заданном отрезке, а задания 31–35 предназначены для ознакомления с приемами вычисления рекуррентных последовательностей (в том числе последовательности Фибоначчи).

Наконец, завершающая часть заданий данной группы (36–40) посвящена вложенным циклам. Ввиду сложности этой темы допустимо не рассматривать ее при первом знакомстве с циклами, а посвятить ей отдельное занятие уже после знакомства с другими вариантами циклов (как это сделано в [10]).

Группа: For (без вложенных циклов)
Разбор в классе: 3, 4, 6, 7, 8, 12, 13, 15, 16, 17, 22, 29, 33
Закрепление материала: 1, 2, 5, 9, 10, 11, 18, 19, 20, 21, 30, 34
Простые задания: 1, 2, 3, 4, 7, 8, 15, 19, 31, 32
Сложные задания: 23, 24, 25, 26, 27, 28, 34, 35
Наборы однотипных заданий: 4–6; 7–13; 15–18; 19–21; 22–28; 29–30; 31–35
Группа: For (вложенные циклы)
Разбор в классе: 37, 39
Закрепление материала: 38, 40
Простые задания: 16
Сложные задания: нет
Наборы однотипных заданий: 36–38; 39–40

Цикл с условием: группа While

[Перейти к формулировкам] [Перейти к началу раздела «Группы заданий»] [Перейти к началу раздела «Указания»]

Задания данной группы формально не зависят ни от темы «условный оператор», ни от темы «цикл с параметром»: для выполнения любого задания группы While достаточно использовать цикл с условием, оператор присваивания и операторы ввода-вывода. В частности, к данной теме можно перейти сразу после изучения темы Boolean (до изучения темы If). Однако, как показывает опыт преподавания, при выполнении заданий из данной группы учащиеся испытывают большие затруднения. По этой причине можно рекомендовать приступить к этой теме уже после знакомства с описанными выше темами, однако не использовать условные операторы и операторы цикла For при выполнении заданий.

Задания 1–5 являются вводными; полезно разобрать задание 3 («если данное целое число является степенью 3, то вывести True, иначе вывести False») и проанализировать два варианта его решения (первый вариант основан на последовательном умножении, второй — на последовательном целочисленном делении с анализом остатка). Интересным является задание 6 о вычислении двойного факториала; если уже изучена тема «Цикл с параметром», то целесообразно сравнить варианты решения задания 6, основанные на применении различных видов циклов.

Задания 7–14 посвящены закреплению приемов, связанных с использованием цикла с параметром. Все эти задания можно разбить на две группы: «найти наименьшее число такое, что ...» (например, «найти наименьшее К такое, что 3K > N, где N дано» — задание 9) и «найти наибольшее число такое, что ...» (например, «найти наибольшее K такое, что 3K < N, где N дано» — задание 10). Следует обсудить конструкции, которые надо использовать для каждого типа заданий.

Задания 15–16 относятся к заданиям с «реальным» содержанием (так, задание 15 посвящено вычислению роста банковского вклада).

Задания 17–21 связаны с анализом цифр целых чисел, и являются обобщением аналогичных заданий из группы Integer.

Отметим задания 22 (проверка числа на простоту) и 23 (нахождение наибольшего общего делителя двух целых чисел), алгоритмы решения которых желательно подробно обсудить.

Задания 24–29 посвящены рекуррентным последовательностям: числам Фибоначчи (24–27) и последовательностям общего вида (28–29). В заданиях 28-29 впервые возникает условие проверки близости двух вещественных чисел.

Задание 30 (на определение числа квадратов, которые можно разместить на данном прямоугольнике, причем все размеры являются вещественными) полезно сравнить с аналогичным заданием 29 из группы Integer.

Следует заметить, что группа While не содержит заданий на вложенные циклы с условием. Однако задания подобного типа в достаточнм количестве имеются в следующей группе (Series).

Группа: While
Разбор в классе: 4, 6, 9, 10, 15, 17, 22, 23, 25, 28
Закрепление материала: 5, 11, 12, 16, 18, 24, 26, 29
Простые задания: 1, 2, 3, 17, 30
Сложные задания: 20, 21, 22, 23, 28, 29
Наборы однотипных заданий: 7–14; 15–16; 17–21; 24–27; 28–29


Указания

Процедуры и функции: группа Proc

[Перейти к формулировкам] [Перейти к началу раздела «Группы заданий»] [Перейти к началу раздела «Указания»]

Данная группа состоит из трех подгрупп: первая содержит задания на разработку процедур (1–15), вторая — на разработку функций (16–36), а третья — дополнительные задания на процедуры и функции (37–60).

Первые две подгруппы группы Proc могут изучаться в любом порядке. Например, в [10] вначале рассматриваются процедуры, а затем — функции. Однако это связано с тем, что предварительно, с применением специальных исполнителей (Робот и Чертежник), изучаются процедуры без параметров, после которых переход к процедурам с параметрам выполняется достаточно просто. Если вспомогательные исполнители не используются, то, возможно, целесообразнее начать с рассмотрения функций, поскольку в этом случае не потребуется сразу изучать различия между входными и выходными параметрами (в заданиях на разработку функций все параметры функций являются входными). Для языков C++ и C#, в которых нет разделения на процедуры и функции, начало изучения данной темы с функций также представляется более оправданным. Отметим, что при изучении данных языков термин «процедура», используемый в заданиях, следует понимать просто как сокращение для функции, не возвращающей значение (аналогичное соглашение используется и в других группах заданий, связанных с разработкой процедур и функций, в частности, в группе Param).

Процедуры с числовыми параметрами

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

Следующая серия заданий (6–9) связана с алгоритмами выделения цифр из целых чисел; таким образом, эти задания представляют собой процедурные обертки заданий из группы Integer. Задания 7–9 имеют дополнительную особенность: в процедуру, которую надо разработать, входит параметр, являющийся одновременно входным и выходным.

Наконец, последняя серия заданий (10–15) связана с обменом содержимым между переменными и включает задания на простой обмен (10), обмен с размещением минимального и максимального значения в указанном порядке (11), простейшую сортировку трех чисел (12–13) и циклический сдвиг трех чисел (14–15). Следует обратить внимание на то, что процедуры, разработанные в некоторых заданиях данной серии, оказываются полезными при выполнении других заданий (процедура Swap из задания 10 может использоваться в задании 11, процедура Minmax из задания 11 может использоваться в заданиях 12 и 13 и т. д.). На возможность подобного «повторного» использования процедур следует обратить внимание учащихся; кроме того, полезно в связи с необходимостью повторного использования рассмотреть правила объединения подобных процедур в модули.

Группа: Proc (процедуры с числовыми параметрами)
Разбор в классе: 4, 7, 10, 11, 12
Закрепление материала: 3, 6, 8, 13, 14
Простые задания: 1, 2, 3, 4, 10
Сложные задания: 7, 9
Наборы однотипных заданий: 1–5; 6–9; 10–15

Функции с числовыми параметрами

Подобно начальным заданиям из подгруппы, посвященной процедурам, задания 16–20, а также 32–33, являются «обертками» простейших линейных алгоритмов. Как и для заданий на процедуры, имеется серия заданий (29–31), связанная с выделением цифр из целых чисел.

Большой набор заданий (23–28) посвящен функциям, возвращающим логические значения. Алгоритмы, используемые в этих заданиях, ранее рассматривались в группах Boolean (24), If (23), While (25–28). Прочие задания данной подгруппы также имеют аналоги среди ранее рассмотренных заданий: задание 22 связано с оператором выбора, задания 21, 34 и 36 связаны с циклами с параметром (нахождение суммы чисел из заданного диапазона, вычисление факториала, вычисления числа Фибоначчи), задание 35 — с циклом с условием (вычисление двойного факториала).

Группа: Proc (функции с числовыми параметрами)
Разбор в классе: 16, 17, 21, 25, 30, 36
Закрепление материала: 18, 19, 27, 31, 34
Простые задания: 16, 17, 18, 24, 32, 33
Сложные задания: нет
Наборы однотипных заданий: 18–20; 24–28; 29–31; 32–33; 34–35

Дополнительные задания на процедуры и функции

Характерной особенностью данного раздела является объединение многих заданий в серии таким образом, что процедуры и функции, реализованные при выполнении предыдущих заданий, оказываются полезными при выполнении последующих. Таковы серии 37–39 (реализация различных вариантов функций для возведения в степень), 46–49 (реализация алгоритмов нахождения наибольшего общего делителя, наибольшего общего кратного и связанных с ними), 50–51 (обработка промежутков времени), 52–55 (обработка дат), 56–60 (обработка геометрических объектов на координатной плоскости). Целесообразно рассмотреть какую-либо одну серию (например, задания 52–54 на обработку дат), оформив все реализованные процедуры и функции в виде модуля, и предложить по аналогичной схеме выполнить задания из другой серии.

Кроме того, имеется набор заданий (40–45), посвященных реализации функций для вычисления элементарных функций с помощью их разложения в ряд. В отличие от аналогичных заданий группы For, здесь требуется использовать не фиксированное количество слагаемых, а то количество, которое обеспечивает требуемую точность результата (точность определяется по величине последнего слагаемого).

Группа: Proc (дополнительные задания на процедуры и функции)
Разбор в классе: 40, 52, 53, 54
Закрепление материала: 41, 50, 51, 55, 56, 57, 58, 59
Простые задания: 37, 38, 56
Сложные задания: 39, 41–45, 47, 60
Наборы однотипных заданий: 37–39; 40–45; 46–49; 50–51


Указания

Последовательности: группа Series

[Перейти к формулировкам] [Перейти к началу раздела «Группы заданий»] [Перейти к началу раздела «Указания»]

В заданиях данной группы впервые потребуется совместно использовать различные управляющие операторы (как правило, условный оператор и один из вариантов оператора цикла). Поскольку в каждом из заданий требуется ввести некоторую последовательность чисел, целесообразно генерировать такую последовательность с помощью датчика псевдослучайных чисел (при условии, что на занятиях не используется электронный задачник Programming Taskbook, который генерирует наборы исходных данных автоматически).

Первые задания данной группы (1–7) посвящены алгоритмам нахождения суммы и произведения; кроме того, в них требуется вывести целые (5) или дробные (6) части данных чисел, а также их округленные значения (7). Таким образом, обсуждение этих заданий — хороший повод ознакомить учащихся с соответствующими функциями используемого языка программирования.

Задания 8–11 посвящены алгоритмам отбора требуемых элементов из исходного набора с фиксированным числом элементов; в заданиях 10–11 удобно использовать операторы явного выхода из цикла (break в Pascal, C++ и C#, Exit For в Visual Basic).

Задания 12–16 посвящены наборам ненулевых целых чисел с заранее неизвестным числом элементов (признаком завершения набора является число 0). Стандартную схему перебора элементов в таком наборе (использующую цикл с условием) можно обсудить на примере первого задания этой группы (12).

Особенностью следующей группы заданий (17–23) является то, что для их успешного выполнения надо хранить в памяти два (или три) последовательных элемента из данного набора. При выполнении этих заданий следует напомнить аналогичные задания из групп For и While на обработку рекуррентных последовательностей (в частности, чисел Фибоначчи).

Отдельную подгруппу заданий (26–40) составляют задания на вложенные циклы. Перед обсуждением заданий этой подгруппы полезно вернуться к группе For и рассмотреть ее подгруппу, связанную с вложенными циклами. Задания 30–40 фактически представляют собой модификации предыдущих заданий группы Series, в которых надо обработать не один, а несколько числовых наборов.

Группа: Series (без вложенных циклов)
Разбор в классе: 5, 6, 7, 9, 10, 12, 15, 17, 22
Закрепление материала: 3, 4, 8, 11, 13, 16, 18, 21
Простые задания: 1, 2, 3, 4
Сложные задания: 23, 24, 25
Наборы однотипных заданий: 1–4; 5–7; 8–11; 12–16; 17–23
Группа: Series (вложенные циклы)
Разбор в классе: 27, 29, 30, 36
Закрепление материала: 28, 31, 35, 37
Простые задания: 26, 27, 28
Сложные задания: 38, 39, 40
Наборы однотипных заданий: 26–28; 29–34; 35–40

Минимумы и максимумы: группа Minmax

[Перейти к формулировкам] [Перейти к началу раздела «Группы заданий»] [Перейти к началу раздела «Указания»]

Данная группа является логическим продолжением группы Series, поскольку в ней также обрабатываются последовательности чисел. Однако все задания в ней связаны с нахождением минимумов, максимумов и связанных с ними характеристик исходных последовательностей.

Следует отметить, что возможен вариант, при котором данная группа рассматривается уже после знакомства с массивами; в этом случае для выполнения заданий группы Minmax можно использовать массивы, что во многих случаях приводит к более простым алгоритмам. При этом учащиеся должны понимать, что все задания группы Minmax (как и группы Series) можно выполнить и без массивов, причем подобный способ будет более эффективным.

Начальный набор заданий (1–11) связан с нахождением «обычных» минимумов и максимумов, а также их номеров. В заданиях 2–3 и 5 дополнительно требуется вычислять те элементы, среди которых надо найти минимумы или максимумы. Отдельная серия заданий (6–11) посвящена ситуации, когда в наборе может оказаться несколько минимальных или максимальных элементов (подобным свойством обладают наборы целых чисел). Заметим, что все элементы наборов вещественных чисел в заданиях предполагаются различными, и на это надо обратить внимание учащихся.

Следующий набор заданий (12–15) посвящен условным минимумам и максимумам, т. е. алгоритмам нахождения минимальных или максимальных элементов среди тех, которые удовлетворяют дополнительным условиям. Важно обратить внимание учащихся на особенности данных алгоритмов по сравнению с алгоритмами нахождения «обычных» минимумов/максимумов.

Отметим задачи (16–18) на нахождение количества элементов, расположенных перед, после или между экстремальными элементами (которые легко сводятся к задачам о нахождении номеров соответствующих экстремальных элементов), а также задачи (19–20) на нахождение количества экстремальных элементов (эти задачи, как и все предыдущие, следует решить за один проход исходного набора данных).

Прочие задания данной группы являются дополнительными. Среди них интерес представляет задание 21 (о нахождении среднего значения всех элементов набора, за исключением минимального и максимального) и задания 22–23 (о нахождении нескольких наименьших или наибольших элементов набора). В заданиях 24–30 предварительно требуется определить сами элементы, среди которых надо найти экстремальные (укажем в качестве примера задание 30, в котором надо найти минимальное количество подряд идущих максимумов).

Группа: Minmax
Разбор в классе: 1, 6, 12, 16, 19, 22
Закрепление материала: 7, 8, 13, 18, 20, 21, 23
Простые задания: 1, 2, 3, 4, 5
Сложные задания: 26, 27, 28, 29, 30
Наборы однотипных заданий: 1–5; 6–11; 12–15; 16–18; 19–20; 22–23; 24–25; 26–28; 29–30


Указания

Одномерные массивы: группа Array

[Перейти к формулировкам] [Перейти к началу раздела «Группы заданий»] [Перейти к началу раздела «Указания»]

Исключительная важность данной группы подчеркивается тем фактом, что в нее входит наибольшее количество заданий: 140. Следует сразу обратить внимание учащихся на то, что хотя правил для описания и использования массивов немного, имеется большое число алгоритмов, которые надо усвоить для успешной работы с массивами.

Учитывая большой размер группы Array, обзор заданий будем проводить по ее подгруппам, явно выделенным в задачнике (аналогичным образом мы будем описывать и все последующие группы задачника).

Формирование массива и вывод его элементов

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

Оставшиеся задания данной подгруппы (7–17) посвящены выводу элементов массива в различном порядке. Начинает эту серию задание на перебор элементов массива в обратном порядке (7). В заданиях 8–10 требуется выполнить перебор элементов массива с четными и/или нечетными значениями (в прямом или обратном порядке), а в заданиях 12–15 — с четными и/или нечетными номерами. В последнем случае естественно использовать выражения 2*i и 2*i – 1 для перебора всех четных и нечетных номеров соответственно, однако при этом важно правильно определить диапазон изменения параметра i.

Необходимо учитывать следующую особенность формулировок учебных заданий: в них всегда говорится о порядковых номерах элементов (а не об их индексах), причем предполагается, что первый элемент массива имеет порядковый номер 1. Эта особенность позволяет единообразно формулировать задания для языков с различным способом индексирования. В то же время она приводит к дополнительным сложностям в тех языках, в которых индексация массивов жестко задана и начинается от 0 (как в C++, С# и Visual Basic .NET), поскольку для этих языков значения индексов элементов отличаются от их порядковых номеров (первый по порядку элемент имеет индекс 0, второй — индекс 1 и т. д.). Для языков Pascal и Visual Basic подобные проблемы не возникают, так как в них можно индексировать элементы массивов от 1.

Задания 16–17 являются дополнительными заданиями повышенного уровня сложности. Например, в задании 17 следует вывести элементы массива А (размера N) в следующем порядке: А1, А2, АN, АN–1, А3, А4, АN–2, АN–3, ... . В этих заданиях впервые возникает необходимость перебирать в цикле не отдельные элементы массива, а группы элементов (в задании 17 это четверки элементов). Далее, в подобной ситуации следует выполнять дополнительные действия после завершения цикла, чтобы обработать оставшиеся элементы, которые не удалось включить в группу (в задании 17 количество таких элементов равно N mod 4, где mod обозначает операцию взятия остатка от деления).

Группа: Array (формирование массива и вывод его элементов)
Разбор в классе: 2, 4, 5, 7, 9, 14
Закрепление материала: 3, 6, 8, 11, 15
Простые задания: 1, 2, 7
Сложные задания: 14, 15, 16, 17
Наборы однотипных заданий: 1–6; 8–10; 11–15; 16–17

Анализ элементов массива

В данной подгруппе не требуется преобразовывать исходный массив: достаточно проанализировать его элементы.

Простейшими заданиями такого рода являются задания 18–19, связанные со сравнением элементов массива между собой. В заданиях 20–23 необходимо обработать элементы массива, расположенные между элементами с указанными порядковыми номерами (или вне указанного диапазона номеров).

Задания 24–27 связаны с анализом закономерности чередования элементов; во всех этих заданиях может оказаться полезным использование оператора явного выхода из цикла.

Особо следует выделить задания 32–36 на нахождение локальных экстремумов (минимумов и максимумов) и задания 37–39 на определение участков монотонного убывания/возрастания, которые также сводятся к нахождению локальных экстремумов. В этих заданиях впервые можно применить полезный прием «фиктивных», или барьерных, элементов, который в данном случае позволит единообразно обработать все элементы массива, несмотря на то что первый и последний элемент имеют по одному соседу, а прочие элементы — по два. Кроме того, в заданиях 36 и 39 полезно указать условие, позволяющее легко проверить, является ли элемент AK локальным экстремумом: для этого выражение (AK – AK–1)*(AK – AK+1) должно быть положительным.

Решения задач 40–43 сводятся к перебору элементов массивов в простом цикле, тогда как для решения задач 44–50 необходимо использовать вложенные циклы, и в этом состоит их главная сложность. По указанной причине в пособиях [1, 5, 8] дается полное решение типовой задачи 47. Следует заметить, что задачи 40–43 можно решить и не используя массивы; учащимся можно предложить реализовать такое решение и сравнить полученный алгоритм с алгоритмом, использующим массив.

Группа: Array (анализ элементов массива)
Разбор в классе: 19, 25, 26, 32, 37, 39, 43, 44, 47
Закрепление материала: 24, 27, 33, 36, 38, 42, 45, 49
Простые задания: 18, 19, 20, 21, 28, 29, 30, 31
Сложные задания: 47, 48
Наборы однотипных заданий: 18–19; 20–23; 24–27; 28–29; 30–31; 32–36; 37–39; 40–42; 45–50

Работа с несколькими массивами

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

Особое место в этой подгруппе занимают задания 63–64, посвященные алгоритму слияния упорядоченных массивов, который обязательно следует разобрать на занятиях. В частности, следует указать на возможность применения в данном алгоритме приема барьерного элемента (для автоматической обработки ситуации, в которой оказывается программа при достижении конца одного из исходных массивов). В то же время следует отметить, что данную задачу можно решить, не используя барьерные элементы.

Группа: Array (работа с несколькими массивами)
Разбор в классе: 54, 60, 63
Закрепление материала: 55, 59, 64
Простые задания: 51, 52, 53
Сложные задания: 63, 64
Наборы однотипных заданий: 55–57; 58–61; 63–64

Преобразование массива

Данная подгруппа начинается с заданий, в которых требуется преобразовать элементы массива по определенному правилу (65–70); при этом сразу следует указать на опасность «преждевременной порчи» изменяемых элементов массива и на вызванную этим необходимость использования вспомогательных переменных. Одновременно следует указать на то, что все задания можно выполнить без использования вспомогательных массивов.

Отметим задание 71 об инвертировании массива (изменении порядка его элементов на обратный) и аналогичные задания 72–73. Эти задания сводятся к перемене местами элементов, симметричных относительно середины массива. При реализации данного алгоритма для массива из N элементов учащиеся часто делают ошибку, выполняя указанную перемену не N div 2 раз (где div обозначает операцию целочисленного деления), а N раз. В результате преобразованный массив не будет отличаться от исходного, поскольку каждая пара симметричных элементов будет меняться местами дважды.

Следующая серия задания посвящена простому (79–82) и циклическому (83–86) сдвигу элементов массива на одну или несколько позиций. При выполнении этих заданий следует обратить внимание на необходимость перебора элементов с конца массива при выполнении правого сдвига и с начала массива при выполнении левого сдвига, а также на необходимость использования вспомогательной переменной при выполнении циклического сдвига. Особо надо остановиться на проблемах, связанных с циклическим сдвигом на несколько позиций, и привести несколько вариантов их решения.

Отметим задания 87–89 о вставке элемента в упорядоченный массив с сохранением его упорядоченности. В задании 89 заранее неизвестно, какой элемент нарушает упорядоченность, что повышает сложность данного задания.

Задания 90–100 посвящены алгоритмам удаления элементов из массива: от самых простых («Удалить элемент с указанным номером» — задание 90) до достаточно сложных (например, «Удалить из массива все элементы, встречающиеся менее трех раз» — задание 98). Следует обратить внимание учащихся на то, что удаление сводится к левому сдвигу оставшихся элементов. Рассмотрев какое-либо задание средней сложности (например, «Удалить из массива все нечетные числа» — задание 92), следует показать, как эффективно реализовать подобное удаление, просматривая массив один раз и сразу перемещая оставляемые элементы на их окончательные позиции.

Задания 101–111 посвящены вставке элементов в массив. Здесь следует отметить, что вставка сводится к правому сдвигу элементов и что важно различать ситуации «вставки перед» и «вставки после» некоторого элемента. В данном случае, как и при изучении заданий на удаление элементов, следует рассмотреть какое-либо из заданий средней сложности (например, «Перед каждым положительным элементом массива вставить элемент с нулевым значением» — задание 108) и обсудить эффективный алгоритм вставки, обеспечивающий немедленное перемещение каждого элемента на его окончательную позицию. Заметим, что при реализации подобного алгоритма может потребоваться предварительно просмотреть весь массив (в задании 108 в ходе этого предварительного просмотра массива надо подсчитать количество его положительных элементов). Все задания на вставку элементов следует выполнять без использования вспомогательных массивов.

Завершающая серия заданий, посвященных преобразованию массива, связана с сортировкой (112–115). Задания 112–114 сформулированы таким образом, что позволяют по самой формулировке ознакомиться с требуемым алгоритмом: сортировкой простым обменом (пузырьковой сортировкой) в задании 112, сортировкой простым выбором в задании 113, сортировкой простыми вставками в задании 114. При выполнении каждого задания требуется выводить содержимое массива после каждого прохода, что обеспечит контроль за выполняемыми действиями. Дополнительное задание 115 описывает способ сортировки, не требующий изменения порядка элементов исходного массива (преобразуется вспомогательный индексный массив).

Группа: Array (преобразование массива)
Разбор в классе: 65, 69, 71, 79, 82, 84, 86, 87, 90, 92, 101, 105, 108, 112
Закрепление материала: 70, 72, 80, 81, 84, 88, 91, 93, 102, 109, 113
Простые задания: 65, 79, 80, 90, 101, 102
Сложные задания: 76, 77, 89*, 96, 97, 98, 99, 100, 115
Наборы однотипных заданий: 65–67; 69–73; 79–82; 83–86; 87–89; 92–94; 95–100; 101–105; 106–111; 112–114

Серии целых чисел

Данная подгруппа заданий специально предназначена для того, чтобы предоставить преподавателю большой набор однотипных задач среднего уровня сложности, посвященных преобразованию массива. Понятие серии элементов массива (набор идущих подряд одинаковых элементов) и ее длины (количество этих элементов; длина может быть равна 1) дается в задаче 116. Задачи 117–122 связаны с изменением длины одной или нескольких серий, задачи 123–124 — с переменой местами двух серий, задачи 125–127 — с заменой серии на один нулевой элемент, задачи 128–130 — с обработкой серий наибольшей длины. В [1, 5, 8] приводится решение задачи 116. Алгоритм этого решения (использующий два вспомогательных массива) после несложных модификаций можно применить и для решения остальных задач данной подгруппы. В качестве альтернативного варианта решения задач 117–130 можно предложить разработать алгоритм, не использующий вспомогательные массивы, однако для ряда заданий (например, 128–130) подобный алгоритм будет достаточно сложным.

Группа: Array (серии целых чисел)
Разбор в классе: 116, 119, 124
Закрепление материала: 117, 120, 128
Простые задания: 116
Сложные задания: 128, 129, 130
Наборы однотипных заданий: 117–120; 121–124; 125–130

Множества точек на плоскости

Эта подгруппа заданий также является дополнительной. Ее особенность — в том, что требуется обрабатывать набор точек на плоскости, для хранения которого можно использовать либо два числовых массива (X и Y), либо один массив A записей (структур) с полями X и Y.

Задачи 131–133 решаются простым перебором исходного набора точек с применением алгоритма нахождения минимума или максимума.

Задачи 134–138 также посвящены нахождению минимумов и максимумов, однако для их решения необходимо организовать перебор пар или троек точек во вложенных циклах.

Наконец, задачи 139–140 посвящены сортировке наборов точек (в каждой из этих задач указывается свой вариант отношения порядка для точек на плоскости).

Группа: Array (множества точек на плоскости)
Разбор в классе: 132, 136, 139
Закрепление материала: 133, 135, 138, 140
Простые задания: 131
Сложные задания: 139, 140
Наборы однотипных заданий: 131–133; 134–138; 139–140


Указания

Двумерные массивы (матрицы): группа Matrix

[Перейти к формулировкам] [Перейти к началу раздела «Группы заданий»] [Перейти к началу раздела «Указания»]

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

Для того чтобы уменьшить количество ошибок, часто возникающих при организации вложенных циклов, рекомендуется предложить учащимся придерживаться ряда соглашений, связанных с именованием параметров циклов. Так, параметру цикла, перебирающего строки, следует присваивать имя i (или данное имя с последующим номером: i1, i2 и т. д.), а параметру цикла, перебирающего столбцы, следует присваивать имя j (возможно, с последующим номером). В индексах элементов матриц следует придерживаться «математического» варианта нумерации строк и столбцов: A[i,j] (первыми указывается номер строки). Следует обратить внимание учащихся на связь между именем индекса и диапазоном его изменения: в циклах по i (т. е. по строкам) параметр i практически всегда будет изменяться от 1 до M, а в циклах по j (по столбцам) — от 1 до N (если в языке используется индексирование от 0, то диапазон изменится соответствующим образом: от 0 до M - 1 для i, от 0 до N - 1 для j). Следование подобным соглашениям существенно уменьшит число ошибок, связанных с неверной индексацией, а также упростит проверку текстов программ.

Формирование матрицы и вывод ее элементов

Формированию матрицы посвящены первые шесть заданий. В заданиях 1–4 требуется сформировать матрицу с одинаковыми строками или столбцами, причем в заданиях 1–2 значения этих строк (столбцов) должны вычисляться по указанной простой формуле (например, 10*i для i-й строки в задании 1), а в заданиях 3–4 эти значения должны браться из исходного одномерного массива. В заданиях 5–6 матрица должна быть сформирована таким образом, чтобы каждая ее строка (или столбец) образовывали арифметическую (соответственно, геометрическую) прогрессию.

Остальные задания (7–16) посвящены выводу элементов матрицы в различном порядке. Помимо рассмотрения этих заданий желательно обсудить приемы, позволяющие вывести на экран всю матрицу, обеспечив при этом правильное выравнивание ее элементов по столбцам.

Наряду с простыми заданиями 7–13, в которых требуется вывести одну или несколько конкретных строк (столбцов) матрицы в определенном порядке, подгруппа содержит сложные (дополнительные) задания, в которых обход элементов матрицы надо проводить другими способами: «уголками» (13–14) и «по спирали» (15–16).

Группа: Matrix (формирование матрицы и вывод ее элементов)
Разбор в классе: 1, 4, 7, 10
Закрепление материала: 2, 3, 5, 8, 12
Простые задания: 1, 2, 7, 8
Сложные задания: 13, 14, 15, 16
Наборы однотипных заданий: 1–2; 3–4; 5–6; 7–8; 9–12; 13–16

Анализ элементов матрицы

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

В некоторых заданиях (32–35) требуется найти первую или последнюю строку (или столбец) матрицы, удовлетворяющую некоторому условию. В подобных заданиях целесообразно использовать оператор явного выхода из внешнего цикла.

Следует обратить внимание на задания 36–37, в которых требуется определить количество строк (столбцов), «похожих» на первую строку (столбец) данной матрицы, причем похожими считаются строки (столбцы), имеющие одинаковые множества значений элементов: например, строки (1, 1, 5, 3) и (5, 5, 1, 3) являются похожими. Эти задания целесообразно рассмотреть в случае, если используемый язык программирования предоставляет средства для работы с множествами (как, например, Pascal). В противном случае решение заданий будет довольно сложным, так как потребует сравнений каждого элемента одной строки со всеми элементами другой строки (и наоборот).

Задания 38–41 связаны с нахождением одинаковых элементов в строках/столбцах, а задания 42–45 — с проверкой упорядоченности элементов в строках/столбцах.

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

Группа: Matrix (анализ элементов матрицы)
Разбор в классе: 19, 32, 36, 43
Закрепление материала: 20, 23, 34, 37, 44
Простые задания: 17, 18, 19, 20
Сложные задания: 36, 37, 40, 41, 46
Наборы однотипных заданий: 17–18; 19–22; 23–28; 29–31; 32–35; 36–37; 38–41; 42–45

Преобразование матрицы

При выполнении заданий из данной подгруппы не следует применять вспомогательные двумерные массивы. Алгоритмы, необходимые для выполнении заданий, ранее уже были рассмотрены для одномерных массивов; в данной ситуации в качестве объектов преобразования выступают не отдельные элементы массива, а строки (или столбцы) матрицы, поэтому соответствующие алгоритмы следует дополнить внутренним циклом, позволяющим обработать требуемым образом все элементы этих строк/столбцов.

Задания 47–60 посвящены перемене местами строк (или столбцов) данной матрицы. При этом в заданиях 55–60 подобная перемена должна выполняться для всех строк/столбцов; например, в задании 59 следует зеркально отразить элементы матрицы относительно ее горизонтальной оси симметрии.

Задания 61–67 посвящены удалению строк (или столбцов) матрицы, а задания 68–73 — вставке в данную матрицу новых строк/столбцов.

Следует обратить внимание на задания 74–75, в которых надо найти и определенным образом изменить локальные минимумы (максимумы) данной матрицы. Поскольку граничные элементы матрицы имеют меньше соседних элементов, чем внутренние (угловые элементы имеют 3 соседа, остальные граничные элементы — 5 соседей, а внутренние элементы — 8 соседей), для единообразной обработки всех элементов матрицы очень удобно использовать фиктивные элементы, которыми следует «окружить» исходную матрицу. Вторая проблема, которую следует решить в этих заданиях, связана с тем, что изменение элементов матрицы может привести к неправильной обработке соседних с ними элементов. Простейший способ решения этой проблемы — использование вспомогательной матрицы, и в данном случае такой способ можно считать допустимым (об этом явно сказано в условии), так как вариант решения, не использующий вспомогательную матрицу, является существенно более сложным для реализации.

Задания 76–79 посвящены сортировке строк (столбцов) матрицы по определенному критерию. Алгоритм сортировки в заданиях не определяется. При выполнении этих заданий полезно вспомнить об индексной сортировке, описанной в задании 115 из группы Array, и обсудить ее преимущества при сортировке «больших объектов» (в данном случае — строк или столбцов). В заданиях 78–79 полезно предварительно сформировать вспомогательный «массив ключей», который использовать при проведении сортировки.

Группа: Matrix (преобразование матрицы)
Разбор в классе: 56, 59, 65, 72, 74, 76
Закрепление материала: 55, 58, 60, 66, 70, 75, 77
Простые задания: 47, 48, 61, 62, 68, 69
Сложные задания: 67, 74, 75, 78, 79
Наборы однотипных заданий: 47–48; 49–54; 55–60; 61–66; 68–73; 74–75; 76–79

Диагонали квадратной матрицы

Данная подгруппа менее тесно связана с заданиями на одномерные массивы, чем предыдущие подгруппы группы Matrix. В заданиях этой подгруппы требуется обработать фрагменты матрицы, связанные с ее диагоналями. Определения главной и побочной диагонали квадратной матрицы даются во вводных заданиях 80–81. Следующий набор заданий (82–87) посвящен обработке всех диагоналей, параллельных главной (или побочной). Ввиду сложности такой обработки, в [1, 5, 8] приводится решение типовой задачи 82, причем в двух вариантах.

Необходимо обратить особое внимание на серию заданий 89–93, в которых требуется обнулить часть элементов, расположенных выше/ниже главной/побочной диагонали (рассматриваются различные комбинации указанных условий) без использования условных операторов. Эти задания позволяют еще раз обсудить приемы, связанные с составлением вложенных циклов в такой ситуации, когда диапазон изменения параметра внутреннего цикла зависит от текущего значения параметра внешнего цикла.

Завершающая часть заданий на матрицы (96–100) связана с их зеркальным отражением относительно главной или побочной диагонали или поворотом на угол 90, 180 или 270 градусов. При выполнении заданий заданиях желательно не использовать вспомогательные матрицы; вместо этого следует организовать перебор пар элементов (или даже четверок в случае заданий 99–100), циклически переходящих друг в друга.

Группа: Matrix (диагонали квадратной матрицы)
Разбор в классе: 81, 82, 88, 90, 92, 96
Закрепление материала: 80, 85, 89, 91, 94, 97
Простые задания: 80, 81
Сложные задания: 98, 99*, 100*
Наборы однотипных заданий: 80–81; 82–87; 88–91; 92–95; 96–100


Указания

Символы и строки: группа String

[Перейти к формулировкам] [Перейти к началу раздела «Группы заданий»] [Перейти к началу раздела «Указания»]

Задания данной группы охватывают большинство алгоритмов, связанных с обработкой символов и строк; при этом они сформулированы таким образом, чтобы их можно было использовать для любого из распространенных языков программирования: Pascal, Visual Basic, C++, C#. При использовании языка Visual Basic версий 5 и 6 в качестве символьных данных рекомендуется применять данные типа String * 1 (хотя допустимым является и обычный тип String).

Символы и их коды. Формирование строк

Данная подгруппа начинается с серии заданий на обработку отдельных символов (1–6): преобразование кода в символ и обратно (1–2), перебор символов, идущих подряд в кодовой таблице (3–5), распознавание цифровых и буквенных символов (6).

Затем идут задания на формирование и простейшую обработку строк (7–12), в которых требуется использовать лишь операцию сцепления, а также функцию, возвращающую длину строки. Следует обратить внимание на задачу 10, в которой требуется сформировать строку, содержащую символы исходной строки в обратном порядке. Три варианта решения этой задачи приводятся в [1, 5, 8]; полезно сравнить эти варианты с решением задачи на инвертирование массива (задача 71 из группы Array).

Группа: String (символы и их коды, формирование строк)
Разбор в классе: 1, 2, 3, 4, 6, 7, 10
Закрепление материала: 5, 8, 9, 11
Простые задания: 1, 2, 3, 7
Сложные задания: нет
Наборы однотипных заданий: 8–9; 10–12

Посимвольный анализ и преобразование строк. Строки и числа

Задачи 13–18 решаются с помощью посимвольного просмотра исходной строки; при этом в задачах 16–18 требуется соответствующим образом преобразовать некоторые символы. Следует отметить, что в некоторых языках для преобразования символов в строке требуется использовать особые средства (например, в Visual Basic для этого предназначен специальный оператор Mid, а в C# для возможности изменения символов строки необходимо использовать особый класс StringBuilder, поскольку строки типа string являются неизменяемыми). При выполнении указанных заданий в некоторых языках (например, Pascal и Visual Basic) удобно использовать оператор выбора.

Оставшиеся задачи данной подгруппы (19–25) связаны с преобразованием строк в числа и чисел в строки. Отметим задачу 19, в которой требуется распознать, содержит ли исходная строка число определенного типа: целого или вещественного (с дробной частью); решение этой задачи приводится в [1, 5, 8]. Следует обратить внимание учащихся на тот факт, что необходимость в подобном распознавании часто возникает в реальных программах при организации надежного ввода числовых данных.

В задачах 19–23, связанных с преобразованием цифровых символов в соответствующие числовые значения, полезно указать простой способ подобного преобразования (достаточно вычесть из кода цифрового символа код символа «0»), а также обратного преобразования однозначного числа в соответствующий ему символ (достаточно найти символ с кодом, равным сумме кода символа «0» и данного числа).

Задачи 24–25, связанные с преобразованием десятичного представления числа в двоичное и обратно, могут рассматриваться как дополнительные.

Группа: String (посимвольный анализ и преобразование строк; строки и числа)
Разбор в классе: 13, 17, 19, 20, 22
Закрепление материала: 14, 18, 21, 23
Простые задания: 13, 14
Сложные задания: 19, 24, 25
Наборы однотипных заданий: 13–15; 16–18; 20–21; 24–25

Обработка строк с помощью стандартных функций. Поиск и замена

Начальные задания данной подгруппы (26–30) позволяют продемонстрировать применение стандартных функций, предназначенных для обработки строк и имеющихся в любом языке программирования (удаление фрагмента строки, получение копии подстроки исходной строки, вставка в строку новой подстроки в требуемой позиции). При выполнении заданий 28–30, связанных с вставкой новых символов или строк в требуемые позиции исходной строки, следует обратить внимание на важность перебора символов исходной строки в обратном порядке.

Завершающая серия заданий данной подгруппы (31–40) посвящена различным вариантам поиска и замены, основанным на применении стандартных функций используемого языка программирования. Она содержит задания на проверку наличия требуемой подстроки (31), определение количества вхождений требуемой подстроки в исходную строку (32), удаление или замену первого, последнего или всех вхождений требуемой подстроки (33–38). Задания 39–40, связанные с поиском в строке начальных или конечных пробелов, могут рассматриваться как дополнительные. Следует обратить внимание на сложности в организации поиска последнего вхождения подстроки для тех языков, в которых отсутствуют соответствующие стандартные функции (например, Pascal или Visual Basic версии 5), а также на стандартную схему, использующую цикл с условием при организации удаления или замены всех вхождений требуемой подстроки в исходной строке.

Группа: String (обработка строк с помощью стандартных функций; поиск и замена)
Разбор в классе: 26, 27, 28, 31, 32, 34, 38
Закрепление материала: 29, 33, 35, 36, 37
Простые задания: 31
Сложные задания: нет
Наборы однотипных заданий: 28–30; 33–38; 39–40

Анализ и преобразование слов в строке

Задания данной подгруппы (41–57) посвящены алгоритмам, относящимся к разбиению исходной строки на отдельные слова. При решении большинства заданий можно использовать «универсальный» алгоритм подобного разбиения, основанный на применении стандартных строковых функций (данный алгоритм подробно описан в [1, 5, 8]). Однако во многих ситуациях более эффективными будут «специализированные» алгоритмы, основанные на посимвольном анализе исходной строки (в частности, на распознавании начала слова по двум соседним символам, первый из которых является пробелом, а второй — не является, а конца слова — по паре символов «не пробел»–«пробел»). Подобные варианты решений также рассмотрены в [1, 5, 8]. Задания 53 и 55–56 связаны с распознаванием в строке знаков препинания; для быстрого распознавания подобных символов можно использовать подходящее множество (в языке Pascal) или строку (в языке Visual Basic), содержащие все знаки препинания; можно также использовать соответствующую функцию, если она имеется в языке (например, IsPunctuation в C#).

Группа: String (анализ и преобразование слов в строке)
Разбор в классе: 41, 42, 47, 50, 52, 53
Закрепление материала: 43, 44, 46, 51, 54, 57
Простые задания: 41, 53, 54
Сложные задания: 48, 49, 51, 55, 56
Наборы однотипных заданий: 41–46; 48–50; 53–54; 55–56

Дополнительные задания на обработку строк

Задания 58–61 в данной подгруппе посвящены обработке имен файлов. Подобную обработку (выделение собственно имени, расширения или требуемого фрагмента пути) можно проводить либо с помощью функций поиска или посимвольного анализа, либо с применением специальных функций для работы с файловыми именами, предусмотренными в используемом языке программирования (например, в языке Delphi Pascal для этих целей служит набор функций вида ExtractFileDir, ExtractFileName, ExtractFileExt и т. д., а в языках платформы .NET — специальный класс Path).

Следующий набор заданий (62–67) посвящен шифрованию строк. Рассматривается два вида шифрования: циклическая замена каждой буквы на букву, расположенную в алфавите на K-й позиции после шифруемой буквы (задания 62–65) и «перемешивание» символов в строке (66–67). При реализации циклической замены символов полезно проанализировать вариант, использующий общую формулу для всех символов (в том числе и для перемещаемых «назад», как, например, буква «я»); в эту формулу будет входить операция взятия остатка от целочисленного деления.

Наконец, отметим задания 69–70, связанные с проверкой правильности расстановки скобок в исходной строке (в задании 69 следует анализировать скобки одного типа «()», а в задании 70 — скобки трех типов «()», «[]» и «{}»). Если в задании 69 достаточно завести счетчик открывающих скобок (который надо увеличивать при появлении открывающей скобки и уменьшать при появлении закрывающей скобки, и при этом следить, чтобы он никогда не принимал отрицательные значения и после просмотра строки был равен 0), то в задании 70 необходимо воспользоваться вспомогательной строкой-«стеком» для хранения открывающих скобок всех типов (верхняя скобка из «стека» удаляется при обнаружении закрывающей скобки того же типа) и учесть различные особые ситуации, которые могут при этом возникать (например, появление закрывающей скобки в случае пустого «стека»).

Группа: String (дополнительные задания на обработку строк)
Разбор в классе: 58, 62, 63, 66, 70
Закрепление материала: 60, 64, 67, 69
Простые задания: 58, 59
Сложные задания: 63, 64, 65, 70
Наборы однотипных заданий: 58–61; 62–65; 66–67


Указания

Двоичные файлы: группа File

[Перейти к формулировкам] [Перейти к началу раздела «Группы заданий»] [Перейти к началу раздела «Указания»]

Во всех рассматриваемых языках программирования имеется четкое разделение файловых структур на два класса: двоичные файлы и текстовые файлы. Двоичным файлам посвящена группа заданий File, текстовым — группа Text. Начинать изучение файлов целесообразно с группы File, так как в некоторых заданиях группы Text используются не только текстовые, но и двоичные файлы.

Основная особенность, отличающая двоичные файлы от текстовых, состоит в возможности прямого доступа к содержимому файла, из которой вытекает также возможность одновременного открытия двоичного файла на чтение и на запись. Кроме того, как правило, двоичные файлы хранят элементы одного типа (что позволяет быстро определять размер файла не в байтах, а в «элементах», и быстро переходить к элементу с требуемым номером). По этой причине в языке Pascal двоичные файлы, содержащие однотипные элементы, называются типизированными.

В языках платформы .NET имеется принципиальная возможность записывать в двоичные файлы данные разных типов, однако при этом могут возникнуть проблемы с правильной интерпретацией содержимого этих файлов при их последующем чтении. В заданиях на обработку двоичных файлов всегда предполагается, что все элементы файлов имеют один и тот же тип (т. е. что все двоичные файлы являются «типизированными» в смысле файлов языка Pascal).

Основные операции с двоичными файлами

Данная подгруппа может быть разделена на две большие части.

Первая часть (задания 1–24) знакомит со стандартными операциями по созданию/открытию/закрытию файла и вводу-выводу его элементов.

Особое место в подгруппе занимает задание 1, в котором предлагается проверить, является ли указанная строка допустимым именем файла. При первом знакомстве с файлами это задание можно не рассматривать, поскольку его оптимальный метод решения заключается в том, чтобы «переложить» проверку допустимости имени на операционную систему, попытавшись создать файл с требуемым именем; при этом основная проблема состоит в «перехвате» сообщения о возможной ошибке, если имя не является допустимым. Таким образом, обсуждение этого задания естественным образом подводит к механизму пользовательской обработки ошибок, возникающих в программе (конструкция On Error в «традиционном» Visual Basic, директива компилятора {$I-} в Delphi Pascal, try-блоки во всех языках, допускающих обработку исключений). Следует заметить, что при выполнении других заданий на обработку файлов (как двоичных, так и текстовых) всегда можно реализовать алгоритм, не требующий пользовательской обработки ошибок.

Однотипные задания 2–3 посвящены созданию нового файла, задание 4 — проверке существования требуемого файла (при этом достаточно воспользоваться соответствующей стандартной функцией, предусмотренной во всех рассматриваемых языках, — Dir в Visual Basic, FileExists в Delphi Pascal и т. д.), задание 5 — определению количества элементов в файле (следует обратить внимание на то, что во всех заданиях под размером двоичного файла понимается его размер «в элементах»). Заметим, что в заданиях 4–5 не требуется организовывать считывание данных из файла (а в задании 4 нет необходимости даже в открытии файла). Наконец, в заданиях 6–7 требуется выполнить чтение элементов с указанными номерами; что естественным образом приводит к рассмотрению прямого способа доступа к элементам файла. Таким образом, при выполнении заданий 2–7 учащиеся знакомятся практически со всеми приемами работы с двоичными файлами (за исключением нескольких специальных возможностей, которые будут рассмотрены позднее).

Задания 8–24 посвящены закреплению полученных знаний. Практически во всех этих и последующих заданиях, связанных с обработкой файлов (за исключением задания 9) не требуется проверять существование исходных файлов: предполагается, что они всегда существуют. При этом задания 8–15 можно считать основными, а оставшиеся задания (16–24) — дополнительными. Дополнительные задания представляют собой переформулировки «на языке файлов» ранее рассмотренных для массивов задач на нахождение локальных экстремумов, анализ возрастающих/убывающих последовательностей и нахождение серий одинаковых чисел.

Вторая часть (задания 25–41) содержит задачи на преобразование существующего файла. Поскольку двоичные файлы можно открыть одновременно на чтение и запись, в ряде простых случае можно выполнить нужное преобразование непосредственно в исходном файле. Однако более простой и универсальный способ преобразования файла состоит во введении вспомогательного (временного) файла, в который записываются преобразованные данные, после чего исходный файл уничтожается, а имя вспомогательного файла заменяется на имя исходного. Оба способа преобразования файла подробно рассмотрены в [1, 5, 8] на примере решения задачи 25. Следует отметить, что в задаче 26 проще использовать непосредственное преобразование исходного файла, тогда как в задачах 27–28 (как и почти во всех последующих задачах этой части) — способ, основанный на применении вспомогательного файла.

Задания 29–34 связаны с удалением элементов из файла. Для удаления конечной (завершающей) части файла (задания 29–30) во многих языках имеются стандартные процедуры, позволяющие обойтись без вспомогательного файла (процедура Truncate в языке Pascal, метод SetLength в языках платформы .NET).

Задания 35–39 связаны с добавлением в файл новых элементов, а 40–41 — с заменой определенных элементов на наборы других элементов. Во всех этих заданиях следует использовать вспомогательные файлы, хотя задания, связанные с добавлением элементов в конец файла (36–37), можно выполнить и без применения вспомогательного файла.

Группа: File (основные операции с двоичными файлами)
Разбор в классе: 2, 4, 5, 6, 7, 25, 29, 31, 36, 40, а также 1
Закрепление материала: 3, 8, 10, 12, 15, 28, 30, 37, 41
Простые задания: 4, 5, 6, 7, 14, 15, 29, 30
Сложные задания: 1, 17, 23, 24, 27
Наборы однотипных заданий: 11–13; 14–15; 18–19; 21–22; 23–24; 29–32; 33–34; 36–36; 38–39; 40–41

Обработка нетипизированных двоичных файлов

Данная подгруппа содержит задания на обработку нетипизированных файлов. Во всех этих заданиях (42–47) заранее неизвестен тип элементов исходных файлов, причем для выполнения задания эта информация и не требуется, поскольку файлы надо обработать «как единое целое»: поменять местами содержимое двух файлов (задание 42), создать копию существующего файла (43), заменить содержимое одного из исходных файлов на содержимое другого (44–45), дописать к одному файлу содержимое другого (46–47). При выполнении задания 42 вместо перемены местами содержимого файлов достаточно выполнить переименование исходных файлов, воспользовавшись при этом вспомогательным промежуточным именем. Для эффективного выполнения заданий на копирование содержимого целесообразно воспользоваться специальными средствами, предусмотренными в большинстве языков программирования (например, процедурами BlockRead и BlockWrite в языке Pascal или аналогичными методами блочного чтения/записи в языках платформы .NET). В случае отсутствия подобных средств (как в Visual Basic) можно работать с нетипизированными файлами как с типизированными файлами, состоящими из отдельных байт, и выполнять их побайтное копирование. В [1, 5, 8] в качестве примера приведены различные варианты решения задачи 43.

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

Группа: File (обработка нетипизированных двоичных файлов)
Разбор в классе: 43
Закрепление материала: 42, 44
Простые задания: 42
Сложные задания: 47
Наборы однотипных заданий: 44–45

Работа с несколькими числовыми файлами. Файлы-архивы

Во всех заданиях данной подгруппы требуется обрабатывать несколько типизированных файлов (входных или выходных). Задание 48, связанное с поэлементным копированием нескольких исходных файлов в один результирующий файл, подробно проанализировано в [1, 5, 8]; в нем для обработки набора исходных файлов целесообразно использовать массив файловых переменных. Аналогичным, хотя и более сложным, является задание 49 (в нем, в отличие от задания 48, исходные файлы могут иметь различный размер).

В заданиях 50–51 требуется выполнить слияние отсортированных файлов в результирующий файл с сохранением упорядоченности элементов. Полезно сравнить разработанный алгоритм решения этих задач с алгоритмом решения задач на слияние массивов (см. задания 63–64 из группы Array).

Задания 52–57 связаны с объединением данных из нескольких однотипных файлов в один файл-архив и последующим извлечением из архива сохраненных в нем данных. Эти шесть заданий составляют две серии по три задания; в каждой серии используется свой формат хранения данных в файле-архиве. Первое задание серии (52 и 55) связано с формированием файла-архива, остальные задания — с извлечением из него данных, причем последнее задание серии (54 и 57) является более сложным.

Группа: File (работа с несколькими числовыми файлами, файлы-архивы)
Разбор в классе: 48, 50, 52, 53
Закрепление материала: 49, 51, 55, 56
Простые задания: 48
Сложные задания: 50, 51, 54, 57
Наборы однотипных заданий: 50–51; 52–57

Символьные и строковые файлы

Данная подгруппа содержит задания на обработку двоичных файлов с символьной информацией (в предыдущих подгруппах группы File использовались только файлы с числовой информацией; исключение составляли некоторые задания на нетипизированные файлы, в которых тип элементов заранее не указывался). Задания на обработку файлов, элементами которых являются символы (58–62), подобны аналогичным заданиям на обработку числовых файлов. Двоичные файлы, содержащие строки (в задачнике такие файлы называются строковыми), имеют ряд особенностей. Прежде всего, надо учитывать, что строковые файлы отличаются от стандартных текстовых файлов, которым посвящена следующая группа заданий (Text). Отличие состоит в формате хранения строк: в заданиях на обработку двоичных строковых файлов предполагается, что все строки в этих файлах занимают участки памяти одинакового размера (что дает возможность прямого доступа к требуемой строке по ее номеру), в то время как в текстовых файлах каждая строка занимает участок памяти, соответствующий ее фактической длине, а признаком конца каждой строки является специальный маркер (в операционной системе Windows маркер конца строки состоит из двух символов с кодами 13 и 10).

При выполнении заданий, связанных со строковыми файлами (63–73), на языке Pascal в средах Delphi, Lazarus и PascalABC.NET соответствующие файловые переменные должны быть описаны как file of ShortString; тем самым для хранения каждого элемента-строки в файле будет выделено 256 байт. В случае языка Visual Basic элементы строковых файлов должны иметь тип String * 80, в случае языка C++ — тип char[80] (при этом «реальный» размер строки при считывании данных из строковых файлов будет определяться правильно). При использовании языков платформы .NET (VB.NET и C#) требуется явным образом дополнять справа пробелами каждую строку, записываемую в строковый файл, чтобы в результате она имела длину 80 символов, а при считывании строк перед их обработкой может потребоваться удалить их завершающие пробелы. При организации прямого доступа к элементам строковых файлов для языков платформы .NET следует учитывать, что каждый строковый элемент занимает в файле 81 байт.

Информация об особенностях работы со строковыми файлами, ввиду ее важности, приведена в окне справки задачника Programming Taskbook на вкладке «Ввод-вывод» (окно справки можно вызвать из окна задачника, нажав клавишу [F1]).

Среди заданий на обработку двоичных строковых файлов следует отметить серию, связанную с обработкой дат (задания 67–73). Даты хранятся в формате «день/месяц/год», где день и месяц задаются двузначным числом, а год — четырехзначным. В некоторых из этих заданий (71–73) требуется сравнивать даты между собой; чтобы избежать большого числа проверок, удобно при подобных сравнениях использовать те же даты, преобразованные к «американскому» формату «год/месяц/день», для которых можно использовать обычное лексикографическое сравнение строк (в языках платформы .NET можно также преобразовать исходные строки к стандартному типу DateTime, для которого уже реализованы операции сравнения).

Группа: File (символьные и строковые файлы)
Разбор в классе: 58, 60, 63, 67, 69
Закрепление материала: 59, 61, 68, 71
Простые задания: 58, 59
Сложные задания: 73
Наборы однотипных заданий: 58–59; 60–61; 64–65; 67–68; 69–72

Использование файлов для работы с матрицами

Последняя подгруппа группы File (задания 74–90) является дополнительной и содержит задания, в которых двоичные файлы используются для хранения элементов матриц, т. е. прямоугольных таблиц чисел. Выполнение этих заданий позволит учащимся изучить альтернативный способ хранения матриц, отличный от ранее рассмотренного способа (в виде двумерных массивов). Как и для других заданий группы File, при их выполнении не следует использовать вспомогательные массивы (поскольку в этом случае задачи сведутся к уже изученным задачам на обработку массивов и, кроме того, решения будут неэффективными по объему используемой памяти).

В заданиях данной подгруппы используются два формата хранения матриц. Первый применяется для квадратных матриц и не требует хранения дополнительных сведений о размере матрицы, так как ее порядок однозначно определяется по размеру файла (с квадратными матрицами связано большинство заданий: 74, 76, 80-90). Второй формат обеспечивает хранение прямоугольных матриц; для того чтобы можно было восстановить размер матрицы, в первый элемент соответствующего файла записывается количество столбцов матрицы (с прямоугольными матрицами связаны задания 75, 77–79). Кроме того, рассматриваются три специальных вида квадратных матриц: верхнетреугольные (80, 83, 86, 89), нижнетреугольные (81, 84, 87, 90) и трехдиагональные (82, 85, 88); с этими видами матриц связываются дополнительные форматы, не содержащие нулевую часть матриц. В заданиях используются также две матричные операции: транспонирование матрицы (75, 78) и перемножение двух матриц (76, 79, 89, 90).

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

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

Группа: File (использование файлов для работы с матрицами)
Разбор в классе: 74, 75
Закрепление материала: 77, 78
Простые задания: 74, 77
Сложные задания: 76, 79, 89*, 90*
Наборы однотипных заданий: 80–82; 83–85; 86–88; 89–90


Указания

Текстовые файлы: группа Text

[Перейти к формулировкам] [Перейти к началу раздела «Группы заданий»] [Перейти к началу раздела «Указания»]

Обработка текстовых файлов во всех рассматриваемых языках программирования имеет ряд особенностей, отличающих ее от обработки двоичных файлов. В частности, при обработке текстовых файлов нельзя использовать средства, связанные с прямым доступом к файловым элементам; кроме того, текстовые файлы нельзя одновременно открыть на чтение и запись, а для дополнения текстового файла его надо открыть в специальном режиме. По этой причине для изучения текстовых файлов разработана специальная группа Text.

В некоторых заданиях этой группы используются не только текстовые, но и двоичные файлы, поэтому приступать к изучению группы Text рекомендуется после изучения группы File.

При выполнении заданий на языках VB.NET и C# с использованием стандартных файловых классов платформы .NET следует учитывать, что по умолчанию при записи текстовых данных эти классы применяют кодировку UTF-8, которая отличается от однобайтной ANSI-кодировки, используемой задачником при формировании исходных файлов и проверке результирующих файлов. Для настройки ANSI-кодировки при работе с файлами необходимо явно указать в конструкторах соответствующих классов параметр System.Text.Encoding.Default. Поскольку это действие является обязательным для правильной работы программ, использующих электронный задачник, информация о нем приводится в разделе «Ввод-вывод» окна справки задачника. Впрочем, в случае, если текстовое содержимое файла не включает русские буквы, параметр System.Text.Encoding.Default можно не указывать, так как ANSI-кодировка символов ASCII (с кодами до 127) совпадает с их кодировкой UTF-8.

Основные операции с текстовыми файлами

Первая подгруппа группы Text знакомит с основными приемами, связанными с созданием и преобразованием текстовых файлов. Задания 1–3 посвящены формированию текстовых файлов, задание 4 — анализу их содержимого, а прочие задания — преобразованию имеющихся файлов. Задания 1 и 4 подробно разбираются в [1, 5, 8]. Поскольку открыть текстовый файл одновременно на чтение и запись нельзя, в большинстве заданий на преобразование файла необходимо использовать вспомогательный файл (как и в аналогичных заданиях на преобразование двоичных файлов). Однако в случае добавления в конец существующего файла новых строк (задания 5–6) можно обойтись без вспомогательного файла, используя специальный режим дополнения (append), на который следует обратить внимание учащихся.

С использованием вспомогательного файла можно легко выполнять такие действия по преобразованию текстового файла, как вставка в его начало или середину новых строк (задания 7–11) или обработка имеющихся строк: замена (12), удаление (13–16) или преобразование (17–18). Следует обратить внимание на задания 19–20, которые можно выполнить двумя способами, используя построчную или посимвольную обработку файла (заметим, что оба указанных способа обработки текстовых файлов приводятся в [1, 5, 8] при разборе заданий 1 и 4).

Завершает данную подгруппу серия заданий 21–23, в которых надо определенным образом обработать завершающую часть исходного файла: удалить требуемое число последних строк из файла (21–22) или скопировать их в новый файл (23). Рекомендуется обсудить эффективный, хотя и достаточно сложный, алгоритм выполнения этих заданий, использующий однократный проход по исходному файлу (различные варианты решения задачи 21 приведены в [1, 5, 8]).

Группа: Text (основные операции с текстовыми файлами)
Разбор в классе: 1, 4, 5, 7, 10, 14, 19
Закрепление материала: 2, 6, 11, 13, 15, 20
Простые задания: 1, 4, 5, 6
Сложные задания: 21, 22, 23
Наборы однотипных заданий: 9–10; 11–12; 15–16; 22–23

Анализ и форматирование текста

Данная подгруппа группы Text включает задания двух типов.

Задания первого типа связаны с анализом и обработкой фрагментов текста, отличных от строк и символов: это абзацы (задания 24–28) и отдельные слова (задания 29–33). Рассмотрены два способа выделения абзацев: с помощью одной или нескольких пустых строк (24–25) и с помощью абзацного отступа — красной строки (26–28). При выполнении заданий 24-25 следует обратить внимание учащихся на необходимость хранения предыдущей файловой строки (текущая непустая строка является началом абзаца, если предшествующая ей строка является пустой). Задания на обработку слов также представлены в двух вариантах: в более простом варианте словом считается последовательность непробельных символов, которая ограничена пробелами или началом/концом строки (задания 29–30), в более сложном варианте слова могут отделяться друг от друга не только пробелами, но и знаками препинания (задания 31–33). Во всех заданиях на обработку слов удобно использовать посимвольный анализ исходного текста.

Задания второго типа связаны с форматированием исходного текста: изменением способа его горизонтального выравнивания (34–37) и изменением ширины текста путем переноса «выступающих» слов на новую строку (38–39). Задачи на изменение ширины текста являются сложными, в то время как в серию задач на выравнивание входят как сравнительно простые задачи 34–36 (на выравнивание текста по левому или правому краю и на его центрирование), так и сложная задача 37, связанная с выравниванием по ширине (за счет добавления между словами дополнительных пробелов).

Группа: Text (анализ и форматирование текста)
Разбор в классе: 24, 25, 34
Закрепление материала: 26, 27, 35, 36
Простые задания: 26, 29, 30
Сложные задания: 37, 38*, 39*
Наборы однотипных заданий: 29–30; 31–33; 34–36

Текстовые файлы с числовой информацией

При работе с текстовыми файлами, содержащими числовую информацию, возникают дополнительные проблемы, связанные, во-первых, с необходимостью форматирования чисел при их записи в текстовый файл и, во-вторых, с необходимостью выделения из текстовой строки числовых данных при их чтении из файла. Форматированию числовых данных при их записи в файл посвящены задания 40–43 и 49, разбору исходных файлов с целью выделения из них числовых данных — задания 44–48 и 50–52.

Во многих заданиях данной подгруппы наряду с текстовыми файлами используются ранее изученные двоичные файлы с числовой информацией.

Задания на форматирование выполняются с применением стандартных средств форматирования, имеющихся в любом из используемых языков программирования. В частности, для языка Pascal можно применять как «старый» способ, основанный на указании форматных настроек через двоеточие, так и новые способы, появившиеся в средах Delphi и Lazarus и связанные с функцией Format (функция Format имеется и в среде PascalABC.NET, хотя в ней применяются форматные настройки другого вида, используемые в языках платформы .NET). В заданиях 40–41 требуется выполнить форматирование целочисленных данных, в заданиях 42–43 — данных вещественного типа (задания 42-43 связаны с табулированием функции, т. е. с формированием таблицы значений функции на некотором наборе равноотстоящих узлов).

Способ выполнения заданий, связанных с выделением из строки числовых данных, зависит от наличия в языке программирования или его стандартной библиотеке соответствующих средств. Если язык позволяет считывать числовые данные из текстовых файлов непосредственно в переменные числовых типов (например, с помощью процедур Read и Readln языка Pascal, оператора Input языка Visual Basic или оператора >> языка C++), то этой возможностью, разумеется, надо воспользоваться. Если же специальных средств для чтения числовых данных из текстовых файлов не предусмотрено (как в стандартной библиотеке ввода-вывода .NET), то необходимо считывать данные в строковые переменные и затем выполнять их преобразование к требуемому числовому типу.

При изучении особенностей чтения числовых данных из текстовых файлов на языке Pascal необходимо обратить внимание учащихся на наличие функции SeekEof, позволяющей вовремя распознать конец файла при считывании из него числовых данных, даже если после чтения последнего числа в файле остаются незначащие символы, например, пробелы.

Группа: Text (текстовые файлы с числовой информацией)
Разбор в классе: 40, 42, 44, 47, 49
Закрепление материала: 41, 43, 46, 51
Простые задания: 40
Сложные задания: 52
Наборы однотипных заданий: 42–43; 44–48

Дополнительные задания на обработку текстовых файлов

Задания этой подгруппы связаны с выделением из исходных текстовых файлов требуемых категорий символов и анализом частоты их появления (задания 53–58), а также с шифрованием/дешифрованием исходного файла (задания 59–60).

При анализе символов, содержащихся в исходном файле, важно использовать оптимальную структуру данных для хранении информации об уже прочитанных и обработанных символах. Если при выполнении задания надо лишь хранить информацию о наличии в исходном файле того или иного символа (задания 54–56), то на языке Pascal в качестве соответствующей структуры можно использовать множество, содержащее символы, прочитанные из файла. Если же необходимо подсчитывать количество появлений каждого символа (задания 57–58), то можно использовать числовой массив, каждый элемент которого соответствует одному из возможных символов, а значение этого элемента равно числу появлений данного символа (на языке Pascal в качестве индексов массива можно использовать символы; таким образом, информация о числе появлений, например, символа «a», будет содержаться в элементе с индексом «a», информация о символе «b» будет содержаться в элементе с индексом «b», и т. д.). Аналогичные структуры можно использовать и для других языков программирования; в частности, если язык не поддерживает работу с множеством, то вместо множества можно использовать массив логических элементов, каждый из которых соответствует одному из возможных символов (элемент равен значению True, если соответствующий символ был прочитан из исходного текста, и False в противном случае).

Для шифрования/дешифрования файла в заданиях 59–60 используется усложненный вариант способа шифрования, основанного на циклическом сдвиге букв алфавита (ранее этот способ был рассмотрен в задачах 62–65 группы String).

Группа: Text (дополнительные задания на обработку текстовых файлов)
Разбор в классе: 54, 55, 57
Закрепление материала: 56, 58
Простые задания: 53
Сложные задания: 58, 59, 60
Наборы однотипных заданий: 54–56; 59–60


Указания

Составные типы данных в процедурах и функциях: группа Param

[Перейти к формулировкам] [Перейти к началу раздела «Группы заданий»] [Перейти к началу раздела «Указания»]

Группа Param содержит задания на обработку одномерных и двумерных массивов, строк и файлов, т. е. тех же структур данных, которые ранее изучались в группах Array, Matrix, String, File и Text. Особенностью заданий группы Param является то, что алгоритмы решения необходимо оформить в виде некоторой процедуры или функции с указанными в условии параметрами. Таким образом, выполняя эти задания, учащиеся, с одной стороны, должны повторить и закрепить знания, связанные с обработкой сложных структур данных, а с другой стороны — вспомнить правила описания и использования процедур и функций (и, кроме того, изучить особенности передачи сложных структур данных в качестве параметров).

Задания группы Param разделены на четыре подгруппы, первые три из которых связаны с одной из ранее изученных структур данных: массивами, строками и файлами. Задания из каждой подгруппы можно предложить для выполнения сразу после изучения соответствующей структуры данных. Можно также организовать «итоговое повторение», обратившись к группе Param после изучения всех ранее рассмотренных групп, связанных со сложными структурами данных.

Особое место занимают задания четвертой подгруппы, предназначенные для изучения новых структурных типов, называемых в языке Pascal записями (в языке Visual Basic подобные типы называются пользовательскими типами данных, а в языках C++, C#, VB.NET — структурами).

Одномерные и двумерные массивы

Задания данной подгруппы можно разделить на две части. В первую часть входят задания, связанные с обработкой одномерных массивов: поиск минимальных/максимальных элементов в массиве (задания 1–3), инвертирование и сглаживание массива (4–7), удаление и вставка элементов (8–10), сортировка (11–13), разбиение исходного массива на два (14–15). Вторая часть содержит задания на обработку двумерных массивов-матриц: формирование матрицы (16–18), вычисление матричной нормы (19–20), вычисление сумм элементов строк или столбцов (21–22), преобразование матрицы, связанное с переменой местами требуемых строк или столбцов (23–24), транспонированием (25). удалением строк и/или столбцов (26–28) и сортировкой столбцов (29).

Многие задания имеют близкие аналоги в группах Minmax, Array и Matrix. Из числа «оригинальных» заданий отметим задания, посвященные сглаживанию массива (5–7), формированию матрицы по исходному одномерному массиву (16–17) и вычислению нормы матрицы (19–20).

При выполнении заданий желательно не использовать вспомогательные массивы, хотя в ряде случаев это ограничение приводит к усложнению алгоритма (см., например, задания 7–10).

Общей чертой многих заданий на обработку матриц является необходимость проверки корректности некоторых параметров. Например, в процедуре нахождения суммы K-й строки матрицы из задания 21 необходимо дополнительно проверять, что параметр K лежит в допустимом диапазоне номеров строк (при нарушении этого условия требуется вывести особое значение 0).

Группа: Param (одномерные и двумерные массивы)
Разбор в классе: 1, 4, 5, 8, 21, 24
Закрепление материала: 2, 3, 10, 22, 23
Простые задания: 1, 2, 3, 18
Сложные задания: 7, 9, 12, 13, 29
Наборы однотипных заданий: 5–6; 14–15; 16–17; 19–20; 21–22; 23–24; 26–27

Строки

Многие из заданий данной подгруппы являются не «процедурными» вариантами ранее рассмотренных заданий группы String, а вполне оригинальными заданиями, среди которых можно выделить задания на проверку корректности идентификатора (задание 30), формирование строки по повторяющемуся шаблону (31), сжатие строки текста с повторяющимися символами по определенной схеме и ее последующее восстановление (42–43).

Некоторые задания требуют разработки процедур и функций, аналогичных тем, которые присутствуют в любой достаточно богатой стандартной библиотеке для работы со строками. К таким заданиям можно отнести задания на изменение регистра символов (32–33), удаление начальных или конечных символов с указанным значением (34–35), инвертирование и поиск (36–39), выделение из строки слов (40–41). Однако даже если при выполнении подобных заданий учащийся воспользуется стандартными подпрограммами, от него все равно потребуется «адаптировать» их к условию задания; описав процедуру или функцию с требуемым именем и указанными в задании параметрами.

Завершающие четыре задания (44–47) посвящены алгоритмам перевода из десятичной системы счисления в двоичную и шестнадцатеричную (и обратно); ранее подобные задания рассматривались в группе String (см. задания 24–25).

Группа: Param (строки)
Разбор в классе: 30, 34, 41
Закрепление материала: 31, 33, 40
Простые задания: 32, 33, 34, 35
Сложные задания: 42, 43, 45, 47
Наборы однотипных заданий: 32–33; 34–35

Файлы

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

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

Задачи на шифрование/дешифрование текстового файла (57–58) также являются процедурными оболочками заданий 59–60 из группы Text, причем в этих задачах предлагается использовать более простой способ шифрования.

К оригинальным заданиям можно отнести задачи на добавление или удаление нумерации строк текстового файла (51–52), на разбиение двоичного или текстового файла на две части (53–54) и на преобразование двоичного строкового файла в текстовый и обратно (55–56). Все эти задания (за исключением задания 52), являются достаточно простыми, однако требуют использования большинства ранее изученных приемов работы с файлами (задание 51 дополнительно требует применения форматного вывода числовых данных). Сложность задания 52, в котором требуется удалить ранее добавленную в текстовый файл нумерацию строк, связана с необходимостью предварительной проверки того, существует ли в исходном файле нумерация строк, и определения формата нумерации, если она существует.

Группа: Param (файлы)
Разбор в классе: 48, 54, 55
Закрепление материала: 49, 50, 53, 56
Простые задания: 48, 49, 55, 56
Сложные задания: 51, 52, 57, 58
Наборы однотипных заданий: 48–49; 51–52; 53–54; 55–56; 57–58

Записи

Задания в данной подгруппе можно разбить на две серии, в каждой из которых используется свои типы-записи: в серии заданий 59–63 это тип TDate, содержащий информацию о дате, в серии 64–70 — типы TPoint (точка на координатной плоскости) и TTriangle (треугольник, заданный своими вершинами). В каждой серии задания должны выполняться последовательно, поскольку в последующих заданиях серии используются типы и подпрограммы, реализованные в предыдущих заданиях. Следует заметить, что аналогичные задания, в которых, однако, не требовалось использовать записи, входят в завершающую подгруппу группы Proc: это задания 52–55 на обработку дат и задания 56–60, связанные с геометрией на плоскости. Полезно сравнить соответствующие задания из групп Proc и Param и обсудить преимущества, которые дает использование новых типов-записей.

Типы и подпрограммы, разработанные в заданиях данной подгруппы, целесообразно сохранять в отдельном модуле, что упростит их использование при выполнении последующих заданий из той же серии. В языках C++, C#, VB.NET можно оформлять подпрограммы, связанные с записями (называемыми в этих языках структурами), в виде методов, входящих в описание этих структур.

Группа: Param (записи)
Разбор в классе: 59, 60, 61, 62
Закрепление материала: 63, 64, 65, 66
Простые задания: нет
Сложные задания: нет
Наборы однотипных заданий: 62–63; 69–70


Указания

Рекурсия: группа Recur

[Перейти к формулировкам] [Перейти к началу раздела «Группы заданий»] [Перейти к началу раздела «Указания»]

Помимо группы Recur рекурсивные алгоритмы рассматриваются в группе Tree, связанной с обработкой деревьев.

Простейшие рекурсивные алгоритмы

Изучение темы «Рекурсия» традиционно начинается с рассмотрения простейших задач (подобных вычислению факториала или двойного факториала — см. задания 1–2), которые, наряду с рекурсивным решением, допускают и «обычное» итерационное решение. Эти задачи позволяют получить первоначальные навыки разработки рекурсивных алгоритмов; однако учащиеся должны четко понимать, что для подобных задач использование рекурсии нередко является не самым лучшим (с точки зрения эффективности) вариантом решения. Для наглядной демонстрации этого обстоятельства полезно рассмотреть хотя бы одно из заданий 4, 6, в которых требуется реализовать рекурсивный алгоритм для вычисления чисел Фибоначчи (задание 4) или числа перестановок Cnk (задание 7), дополнительно определив количество вызовов рекурсивной функции, и убедиться в том, что это количество будет очень быстро расти при увеличении значений параметров рекурсивных функций. В заданиях 5, 7 приводится вариант решения проблемы, связанной с быстрым ростом числа рекурсивных вызовов; он состоит в использовании вспомогательного массива, содержащего уже вычисленные значения рекурсивной функции.

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

Группа: Recur (простейшие рекурсивные алгоритмы)
Разбор в классе: 1, 4, 5, 11, 13
Закрепление материала: 2, 6, 7, 10, 12
Простые задания: 1, 2
Сложные задания: нет
Наборы однотипных заданий: 1–2

Разбор выражений

Разбор выражений представляет собой один из типов задач, для эффективного решения которых необходимо использовать рекурсию. В то же время, задачи этого типа являются достаточно сложными (требующими, как правило, реализации набора связанных подпрограмм, в которых, к тому же, может возникать косвенная рекурсия). Ввиду сложности подобных задач в пособиях [1, 5, 8] приводятся подробные решения целой серии задач из этой группы (14–16, 18), связанной с разбором арифметических выражений (в частности, рассматриваются выражения, в которых необходимо учитывать приоритет операций, и выражения, содержащие скобки).

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

Наряду с заданиями на разбор арифметических выражений (14–19) подгруппа включает задания на разбор выражений, содержащих вызовы функций нахождения минимальных/максимальных значений (20, 22) или вызовы логических функций (21, 23–24). В заданиях 22–24 дополнительно предполагается, что указанные в исходном выражении функции могут иметь переменное число параметров.

Группа: Recur (разбор выражений)
Разбор в классе: 17, 18, 21
Закрепление материала: 19, 20, 23
Простые задания: 14, 17
Сложные задания: 16, 22, 23, 24
Наборы однотипных заданий: 20–21; 22–23

Перебор с возвратом

Данная подгруппа содержит шесть заданий (25–30), в которых необходимо реализовать рекурсивный перебор «разветвляющихся» данных (деревьев). Соответствующий алгоритм называется алгоритмом перебора с возвратом. В отличие от заданий, входящих в группу Tree, в данной подгруппе рассматриваются деревья специального вида — полные деревья степени K, в которых все внутренние вершины имеют K непосредственных потомков, а все листья находятся на одном и том же уровне N. Это позволяет рассмотреть сущность алгоритма перебора с возвратом, не «отвлекаясь» на вопросы, связанные с организацией хранения в памяти деревьев произвольной структуры.

Алгоритм решения первого из заданий данной подгруппы (на перебор всех маршрутов, ведущих от корня дерева к его листьям) подробно описывается в [1, 5, 8]; для решения остальных заданий, в которых требуется найти маршруты, удовлетворяющие дополнительным условиям, достаточно использовать модификации этого алгоритма.

В заданиях 27–30 с вершинами дерева связываются определенные весовые значения (равные –1, 0 и 1), которые следует учитывать при отборе допустимых маршрутов. В частности, в заданиях 28–29 требуется отобрать маршруты, для любого начального участка которых суммарный вес вершин неотрицателен (28) или неположителен (29); в задании 29 дополнительно требуется, чтобы суммарный вес всех вершин маршрута был равен 0. На примере этих заданий можно обсудить прием отсечения, позволяющий отбрасывать некоторые недопустимые маршруты, не доводя их построение до конца, что существенно ускоряет перебор вариантов.

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

Группа: Recur (перебор с возвратом)
Разбор в классе: 25, 27
Закрепление материала: 26, 28
Простые задания: 25
Сложные задания: 29, 30
Наборы однотипных заданий: 27–28; 29–30


Указания

Динамические структуры данных: группа Dynamic

[Перейти к формулировкам (.NET)] [Перейти к началу раздела «Группы заданий»] [Перейти к началу раздела «Указания»]

В заданиях группы Dynamic и следующей за ней группы Tree используются цепочки узлов-записей, связанных между собой ссылочными полями. С помощью подобных цепочек можно реализовать различные динамические структуры данных: стек, очередь (односвязные цепочки, использующие единственное поле связи Next), список (двусвязные цепочки, использующие два поля связи: Next и Prev), бинарное дерево (иерархические цепочки, позволяющие связывать каждый узел-вершину с двумя потомками, используя поля связи Left и Right). Таким образом, задания этих групп позволяют познакомиться с особенностями использования ссылочных типов и изучить основные динамические структуры данных.

В языках программирования, поддерживаемых электронным задачником Programming Taskbook, работа со ссылочными типами организуется одним из двух различных способов. Языки Pascal и C++ используют для этого указатели, в то время как для языков платформы .NET (C# и VB.NET) стандартным является другой подход, основанный на использовании объектов классового (т. е. ссылочного) типа. По этой причине группы Dynamic и Tree, в отличие от всех остальных базовых групп задачника, реализованы в двух вариантах.

В первом варианте задания формулируются в терминах указателей, а для создания динамических структур используется специальный тип-запись TNode, содержащий поле данных Data целого типа и одно или несколько полей связи типа PNode, являющихся указателями на записи типа TNode. Этот вариант реализован для языков Pascal и C++.

Во втором варианте задания формулируются в терминах объектов ссылочного типа, а для создания динамических структур используется специальный ссылочный тип — класс Node с набором свойств, включающим свойство Data целого типа и одно или несколько свойств связи типа Node. Этот вариант реализован для языков C# и VB.NET.

В языке Visual Basic отсутствуют средства создания динамических структур данных, основанных на использовании ссылочных типов. Поэтому в базовый набор заданий для языка Visual Basic группы Dynamic и Tree не включены. В наборе для языка PascalABC.NET, напротив, эти группы присутствуют в двух вариантах, поскольку язык PascalABC.NET сочетает в себе возможности как «стандартного» языка Pascal (и тем самым позволяет использовать указатели), так и языка платформы .NET. Варианты групп Dynamic и Tree, связанные со ссылочными объектами и предназначенные для использования в системе PascalABC.NET, имеют специальные имена: ObjDyn и ObjTree. Таким образом, при изучении линейных динамических структур и бинарных деревьев в системе PascalABC.NET преподаватель имеет возможность выбирать между двумя подходами: с использованием указателей и с использованием объектов ссылочного типа.

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

Стек

Первые два задания данной подгруппы (1 [net]–2 [net]) имеют вводный характер и знакомят с понятиями узла и цепочки узлов. В них не требуется создавать или модифицировать узлы и их связи — достаточно лишь проанализировать состав предложенной односвязной цепочки узлов.

В остальных заданиях подгруппы цепочка узлов интерпретируется как динамическая структура «стек». В них требуется либо добавить к стеку один или несколько новых элементов-узлов (3 [net]–4 [net]), либо извлечь из стека один или несколько имеющихся элементов (5 [net]–7 [net]), либо перераспределить элементы между несколькими исходными стеками (8 [net]–10 [net]).

При выполнении заданий на добавление элементов в стек учащиеся знакомятся с операциями выделения динамической памяти (для языков Pascal и C++) или с использованием конструктора объекта (для языков C# и VB.NET). При выполнении заданий на извлечение элементов из стека для языков Pascal и C++ требуется освобождать динамическую память, вызывая соответствующую процедуру (при использовании языков платформы .NET также требуется выполнять специальные действия по освобождению выделенных ресурсов, вызывая специальный метод Dispose класса Node). При перераспределении имеющихся элементов не требуется ни выделять, ни освобождать память.

Три завершающих задания данной подгруппы посвящены разработке вспомогательных подпрограмм, упрощающих работу со стеком: Push (добавление элемента в стек — задание 11 [net]), Pop (извлечение элемента из стека — задание 12 [net]), Peek и IsEmpty (просмотр верхнего элемента стека и проверка стека на непустоту — задание 13 [net]). Способ оформления этих подпрограмм зависит от используемого языка программирования: для языков Pascal и C++ подпрограммы должны работать со специальным типом — записью с единственным полем Top (указатель на вершину стека), для языков платформы .NET требуется реализовать новый класс с закрытым полем top, включив в этот класс все указанные выше подпрограммы в виде открытых методов.

Группа: Dynamic (стек)
Разбор в классе: 2 [net], 3 [net], 4 [net], 6 [net], 11 [net]
Закрепление материала: 5 [net], 7 [net], 8 [net], 12 [net]
Простые задания: 1 [net], 3 [net], 5 [net]
Сложные задания: нет
Наборы однотипных заданий: 6 [net]–7 [net]

Очередь

Состав заданий, посвященных обработке динамической структуры «очередь», подобен составу заданий, связанных с обработкой стека: вначале идут задания, связанные с формированием очереди и добавлением в нее новых элементов (14 [net]–17 [net]), затем — с извлечением элементов из очереди (18 [net]–19 [net]) и наконец — с обработкой существующих очередей, связанной с перераспределением их элементов (20 [net]–25 [net]).

Общей чертой заданий на стеки и очереди является то, что в обоих случаях структуры моделируются односвязной цепочкой узлов. Однако задания, связанные с очередями, являются более сложными, чем аналогичные задания для стеков. Это объясняется, прежде всего, необходимостью специальной обработки особых ситуаций: извлечения из очереди последнего элемента, в результате чего очередь становится пустой, и добавления к пустой очереди первого элемента. В подобных ситуациях для стека особой обработки не требовалось, так как ссылка на вершину стека изменялась автоматически. Для очереди требуются дополнительные действия, обусловленные тем, что с очередью связываются две ссылки: на начало очереди (из которого извлекаются элементы) и на ее конец (к которому добавляются новые элементы).

Из заданий на преобразование очередей следует выделить задание 25 [net], в котором требуется выполнить слияние двух упорядоченных очередей в новую очередь с сохранением упорядоченности. Полезно сравнить разработанный алгоритм с аналогичными алгоритмами для слияния массивов (задания 63–64 группы Array) и файлов (задания 50–51 группы File).

Завершают данную подгруппу (как и подгруппу, посвященную стекам) три задания на разработку подпрограмм, предназначенных для обработки очередей: Enqueue (добавление элемента в очередь — задание 26 [net]), Dequeue (извлечение элемента из очереди — задание 27 [net]), IsEmpty (проверка очереди на непустоту — задание 28 [net]). Как и в случае со стеком, способ оформления данных подпрограмм зависит от используемого языка программирования. При разработке подпрограмм Enqueue и Dequeue следует обратить внимание на необходимость дополнительной обработки отмеченных выше особых ситуаций.

Группа: Dynamic (очередь)
Разбор в классе: 16 [net], 19 [net], 22 [net], 25 [net], 26 [net]
Закрепление материала: 15 [net], 20 [net], 23 [net], 24 [net], 27 [net]
Простые задания: 17 [net], 18 [net]
Сложные задания: 19 [net], 20 [net], 22 [net], 23 [net], 24 [net], 25 [net]
Наборы однотипных заданий: 19 [net]–20 [net]; 22 [net]–23 [net]; 24 [net]–25 [net]

Двусвязный список

Основное отличие заданий на двусвязные списки от ранее рассмотренных заданий на стеки и очереди состоит в том, что в цепочках элементов-узлов, моделирующих списки, каждый элемент связывается с обоими своими соседями: со следующим элементом посредством поля Next, а с предыдущим — посредством поля Prev (в случае языков платформы .NET вместо полей используются одноименные свойства класса Node). Первый элемент списка содержит пустую ссылку Prev, а последний — пустую ссылку Next. Наличие двойной связи и необходимость особым образом обрабатывать «концевые» элементы списков приводит к усложнению алгоритмов обработки списков (по сравнению с аналогичными алгоритмами обработки стеков и очередей). Кроме того, для списков вводится понятие текущего элемента, для которого определяются дополнительные действия, отсутствующие у стеков и очередей: добавление нового элемента перед или после текущего и удаление текущего элемента (все эти действия должны сохранять целостность двусвязной цепочки).

Подобно подгруппе, связанной со стеком, подгруппа для списка начинается с двух заданий (29 [net]–30 [net]), посвященных знакомству с двусвязными цепочками. Следует обратить внимание на задание 30 [net], в котором требуется преобразовать исходную односвязную цепочку в двусвязную. В других заданиях подобные действия выполнять не придется, поскольку все исходные списки уже являются двусвязными.

Последующие задания можно разбить на несколько серий:

  • простейшие задания на перемещение по списку в различных направлениях и вставку в его начало/конец или в требуемую позицию нового элемента (31 [net]–36 [net]);
  • более сложные задания на вставку элементов, в которых требуется продублировать в списке набор элементов с определенными свойствами, например, имеющих четный/нечетный порядковый номер или четное/нечетное значение (37 [net]–40 [net]);
  • задания на удаление одного (41 [net]) или нескольких (42 [net]–43 [net]) требуемых элементов из списка;
  • задания, связанные с перемещением некоторого элемента списка вперед или назад на указанное число позиций (44 [net]–47 [net]);
  • более сложные задания на перегруппировку элементов списка, включающие перемену местами двух указанных элементов (48 [net]) и перемещение элементов с требуемыми свойствами в конец списка (49 [net]–50 [net]);
  • задания, связанные с обработкой нескольких списков: вставка всех элементов одного списка в указанную позицию другого (51 [net]–52 [net]) и обратная задача: извлечение отмеченного фрагмента из списка и оформление извлеченного фрагмента как нового списка (53 [net]–54 [net]).

Задания 55 [net]–58 [net] посвящены особой разновидности списков — циклическим спискам, которые моделируются замкнутой цепочкой узлов (замкнутые цепочки рассматриваются также в следующей подгруппе, посвященной другому варианту реализации двусвязного списка). Следует отметить задания 57 [net]–58 [net], в которых с помощью «сшивания» исходного списка в циклический и последующего «разрыва» этого списка в новой позиции требуется реализовать циклический сдвиг элементов списка на указанное количество позиций вперед или назад.

Как и в предыдущих подгруппах, заключительные задания (59 [net]–69 [net]) посвящены реализации подпрограмм, выполняющих различные стандартные операции над списком. Количество подобных заданий достаточно велико, поскольку для списков можно определить много различных операций. При реализации всех операций предполагается, что со списком связываются три ссылки: на начало списка (First), на его конец (Last) и на его текущий элемент (Current); для пустого списка все эти ссылки должны быть пустыми. Перечислим операции, которые требуется реализовать:

  • различные операции, связанные со вставкой элемента: InsertLast/InsertFirst (добавление в конец/начало списка — задания 59 [net]–60 [net]), InsertBefore/InsertAfter (вставка перед/после текущего элемента списка — задания 61 [net]–62 [net]);
  • операции, обеспечивающие перемещение по списку вперед/назад, а также доступ к значениям элементов списка на чтение/запись (ToFirst/ToLast, ToNext/ToPrev, IsLast/IsFirst, GetData/SetData — задания 63 [net]–64 [net]);
  • операция, связанная с удалением текущего элемента списка (DeleteCurrent — задание 65 [net]); сложность этой операции обусловлена необходимостью обработки большого числа различных особых ситуаций;
  • операции, связанные с обработкой нескольких списков: Split (расщепление списка на два — задание 66 [net]), Add (добавление одного списка в конец другого — задание 67 [net]), Insert (вставка одного списка перед текущим элементом другого — задание 68 [net]), MoveCurrent (перемещение текущего элемента одного списка в другой список — задание 69 [net]); последняя операция, подобно операции DeleteCurrent, является сложной для реализации.
Группа: Dynamic (двусвязный список)
Разбор в классе: 30 [net], 31 [net], 34 [net], 41 [net], 55 [net], 57 [net], 59 [net], 63 [net]
Закрепление материала: 32 [net], 33 [net], 40 [net], 56 [net], 58 [net], 60 [net], 64 [net]
Простые задания: 29 [net], 31 [net], 33 [net], 34 [net], 35 [net], 36 [net], 41 [net], 55 [net]
Сложные задания: 46 [net], 47 [net], 48 [net], 49 [net], 50 [net], 65 [net], 69 [net]
Наборы однотипных заданий: 33 [net]–34 [net]; 35 [net]–36 [net]; 37 [net]–40 [net]; 42 [net]–43 [net]; 44 [net]–45 [net]; 46 [net]–47 [net]; 49 [net]–50 [net]; 51 [net]–52 [net]; 53 [net]–54 [net]; 57 [net]–58 [net]; 59 [net]–60 [net]; 61 [net]–62 [net]; 63 [net]–64 [net]; 67 [net]–68 [net]

Список с барьерным элементом

Последняя подгруппа группы Dynamic может рассматриваться как дополнительная, поскольку в ней не вводится новая динамическая структура, а по-прежнему изучается двусвязный список. Эта подгруппа посвящена варианту реализации двусвязного списка, в котором для хранения элементов используется замкнутая цепочка узлов, снабженная особым узлом — барьерным элементом списка. Элемент, следующий за барьерным, считается первым элементом списка, элемент, предшествующий барьерному, — последним элементом. Пустой список моделируется единственным барьерным элементом, «замкнутым на себя».

При реализации списка с использованием барьерного элемента нет необходимости хранить ссылки на его начало и конец; достаточно хранить одну ссылку на барьерный элемент, используя которую можно сразу перейти и к первому, и к последнему элементу списка. Еще одним преимуществом этой реализации является отсутствие пустых ссылок: даже при извлечении из списка всех «настоящих» элементов в нем останется барьерный элемент. Кроме того, при любых преобразованиях списка ссылка не его барьерный элемент не изменяется (в отличие от прежней реализации, в которой требуется хранить ссылки на первый и последний элементы списка, которые могут изменяться).

В первом задании данной подгруппы (70 [net]) требуется преобразовать «обычную» двусвязную цепочку с пустыми ссылками на концах в замкнутую цепочку с барьерным элементом, т. е. перейти от старого к новому представлению двусвязного списка. В последующих заданиях исходные списки уже представлены в виде замкнутых цепочек с барьерными элементами. В задании 71 [net] требуется разбить список на два, в заданиях 72 [net]–73 [net] — объединить два списка в один с сохранением первоначальной структуры.

Заключительные задания (74 [net]–80 [net]) посвящены, как обычно, реализации подпрограмм, выполняющих стандартные операции над списком:

  • вставку элемента: InsertLast/InsertFirst (добавление в конец/начало списка — задания 74 [net]–75 [net]), InsertBefore/InsertAfter (вставка перед/после текущего элемента списка — задания 76 [net]–77 [net]);
  • перемещение по списку вперед/назад и доступ к значениям элементов списка на чтение/запись (ToFirst/ToLast, ToNext/ToPrev, IsBarrier, GetData/SetData — задания 78 [net]–79 [net]);
  • удаление текущего элемента списка (DeleteCurrent — задание 80 [net]).

Полезно сравнить реализации этих подпрограмм с реализациями аналогичных подпрограмм для «старого» представления списка. Новые варианты будут существенно проще, поскольку в них не потребуется предусматривать обработку особых ситуаций, связанных с пустыми ссылками (особенно сильно упростится реализация подпрограммы DeleteCurrent). Следует также обратить внимание на функцию IsBarrier (задание 78 [net]), используемую вместо пары функций IsFirst/IsLast. Применение функции IsBarrier упрощает перебор элементов списка, поскольку не требует особой обработки первого или последнего элемента (которую неизбежно надо выполнять при использовании функций IsFirst/IsLast). Полезно сравнить функцию IsBarrier с аналогичной функцией, позволяющей проверить, что достигнут конец файла (например, Eof для языка Pascal).

Группа: Dynamic (список с барьерным элементом)
Разбор в классе: 71 [net], 74 [net], 78 [net], 80 [net]
Закрепление материала: 72 [net], 75 [net], 76 [net], 79 [net]
Простые задания: 70 [net]
Сложные задания: нет
Наборы однотипных заданий: 72 [net]–73 [net]; 74 [net]–75 [net]; 76 [net]–77 [net]; 78 [net]–79 [net]


Указания

Бинарные деревья: группа Tree

[Перейти к формулировкам (.NET)] [Перейти к началу раздела «Группы заданий»] [Перейти к началу раздела «Указания»]

В заданиях группы Tree, как и в заданиях группы Dynamic, используются цепочки элементов-записей, связанных между собой ссылочными полями, поэтому все, сказанное выше об особенностях группы Dynamic, относится и к группе Tree. В частности, реализованы два варианта заданий этой группы: в первом варианте задания формулируются в терминах записей и указателей на них (этот вариант предназначен для языков Pascal и C++), во втором — в терминах объектов ссылочного типа (этот вариант предназначен для языков платформы .NET). Для языка Visual Basic группа Tree, как и группа Dynamic, не реализована. В языке PascalABC.NET можно использовать оба варианта группы Tree; при этом название Tree оставлено для варианта, связанного с указателями, а вариант, связанный со ссылочными объектами, получил название ObjTree.

Основное отличие цепочек узлов, рассматриваемых в группе Tree, от цепочек группы Dynamic состоит в том, что в группе Tree цепочки являются иерархическими: с каждым узлом (вершиной дерева) могут быть связаны два непосредственных потомка (левая и правая дочерняя вершина); связь осуществляется с помощью ссылочных полей узла-предка Left и Right; возможна также «обратная связь» от потомка к предку (родительской вершине), которая обеспечивается полем Parent потомка (такой вариант деревьев называется в задачнике деревьями с обратной связью). Общий предок всех вершин непустого дерева называется корнем. С помощью подобных иерархических цепочек можно моделировать не только бинарные деревья, но и деревья с произвольным ветвлением, вершины которых могут иметь произвольное число дочерних вершин (такой вариант деревьев называется в задачнике деревьями общего вида).

Вершины дерева в задачнике моделируются тем же типом данных, что и элементы линейных динамических структур (для языков Pascal и C++ это запись TNode и указатель на нее PNode, для языков платформы .NET — класс Node). Различие состоит в полях, используемых для связи вершин: если для линейных структур это поля Next и, возможно, Prev (для двусвязных списков), то для деревьев это поля Left, Right и, возможно, Parent (для деревьев с обратной связью).

Как и в случае подгрупп группы Dynamic, связанных с различными видами линейных динамических структур (стек, очередь, список), большинство подгрупп группы Tree связаны с различными видами деревьев. Основному объекту данной группы — бинарному дереву — посвящены три первые подгруппы, затем рассматриваются бинарные деревья с обратной связью, бинарные деревья поиска, бинарные деревья разбора выражений и, наконец, деревья общего вида.

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

В заключение обзора группы Tree отметим, что она связана не только с группой Dynamic, но и с группой Recur, поскольку большинство алгоритмов анализа и обработки деревьев являются рекурсивными.

Анализ бинарного дерева

В первой подгруппе группы Tree не требуется создавать или преобразовывать деревья; достаточно проанализировать содержимое исходного дерева.

Первые два задания (1 [net]–2 [net]) знакомят учащегося со структурой бинарного дерева и связанными с ним понятиями. В задании 2 [net] требуется определить общее количество вершин дерева; рекурсивный алгоритм, решающий эту задачу (см. [7, 8]), с некоторыми модификациями будет использоваться и для последующих заданий 3 [net]–5 [net], связанных с перебором всех вершин (нахождение количества вершин, удовлетворяющих определенному условию, и нахождение суммы значений всех вершин дерева).

В задании 6 [net] вводится понятие листа дерева (вершины, не имеющей дочерних вершин); задания 6 [net]–8 [net] связаны с обработкой листьев.

В задании 9 [net] вводится понятие уровней дерева; задания 9 [net]–11 [net] (а также задание 18 [net]) связаны с анализом дерева по его уровням. По сравнению с остальными заданиями данной подгруппы задания 9 [net]–11 [net] имеют повышенную сложность, поскольку требуют существенной модификации базового рекурсивного алгоритма перебора вершин. В частности, при выполнении заданий 10 [net]–11 [net], в которых для каждого уровня дерева требуется определить некоторую его характеристику (количество вершин, расположенных на этом уровне, или сумму их значений), необходимо использовать вспомогательный массив, элементы которого будут содержать требуемые характеристики уровней. Этот массив должен быть описан как внешний по отношению к рекурсивной процедуре, обеспечивающей перебор вершин.

Задания 12 [net]–14 [net] вводят понятия инфиксного, префиксного и постфиксного порядков перебора элементов дерева. Данные задания являются достаточно простыми (требуется вывести все элементы дерева в указанном порядке); задания 15 [net]–17 [net] являются их более сложными модификациями.

Завершающие задания данной подгруппы (19 [net]–24 [net]) предназначены для закрепления навыков рекурсивного перебора вершин дерева. Все они связаны с нахождением минимальных/максимальных значений вершин дерева, в том числе условных минимумов/максимумов (например, в задании 21 [net] требуется найти минимальное значение среди листьев дерева).

Группа: Tree (анализ бинарного дерева)
Разбор в классе: 2 [net], 6 [net], 9 [net], 12 [net], 23 [net]
Закрепление материала: 3 [net], 7 [net], 10 [net], 13 [net], 24 [net]
Простые задания: 1 [net], 2 [net], 3 [net], 4 [net], 5 [net], 6 [net], 7 [net], 12 [net], 13 [net], 14 [net]
Сложные задания: 9 [net], 10 [net], 11 [net], 18 [net]
Наборы однотипных заданий: 2 [net]–7 [net]; 10 [net]–11 [net]; 12 [net]–14 [net]; 15 [net]–17 [net]; 19 [net]–22 [net]; 23 [net]–24 [net]

Формирование бинарного дерева

При создании бинарного дерева необходимо выделять память для хранения его вершин; поэтому в заданиях этой подгруппы требуется использовать либо соответствующие стандартные процедуры выделения памяти (для языков Pascal и C++), либо подходящие варианты конструктора класса Node (для языков платформы .NET).

Первые шесть заданий этой подгруппы (25 [net]–30 [net]) связаны с формированием бинарных деревьев специального вида (например, в задании 25 [net] требуется создать дерево, каждая вершина которого, кроме корня, является правой дочерней вершиной). В этих заданиях, в отличие от последующих, не требуется использовать рекурсию.

Завершающие задания посвящены трем алгоритмам, связанным с созданием дерева требуемой глубины (31 [net]), идеально сбалансированного дерева (32 [net]–33 [net]) и копии существующего дерева (34 [net]). Поскольку идеально сбалансированное дерево с указанными значениями можно создать различными способами, в задании 32 [net] описывается один из вариантов соответствующего алгоритма, который требуется использовать при выполнении заданий 32 [net]–33 [net] (решение задачи 32 [net] приведено в [7, 8]).

Группа: Tree (формирование бинарного дерева)
Разбор в классе: 26 [net], 32 [net], 34 [net]
Закрепление материала: 27 [net], 31 [net], 33 [net]
Простые задания: 25 [net]
Сложные задания: 31 [net]
Наборы однотипных заданий: 26 [net]–27 [net]; 28 [net]–29 [net]; 32 [net]–33 [net]

Преобразование бинарного дерева

В данной подгруппе содержатся задания на различные виды преобразований бинарных деревьев. В заданиях 35 [net]–39 [net] рассматриваются простейшие преобразования, не связанные с добавлением или удалением вершин (изменение значений и перемена местами вершин). Задания 40 [net]–43 [net] связаны с удалением части вершин. В этих заданиях, как и в аналогичных заданиях на удаление элементов линейных структур, требуется выполнять дополнительные действия по освобождению выделенных ресурсов (например, для языка Pascal надо вызывать стандартную процедуру Dispose, а для языков платформы .NET - метод Dispose класса Node). Следует обратить внимание на задание 40 [net], в котором требуется реализовать алгоритм удаления всех вершин дерева, кроме корня.

Завершающие задания данной подгруппы (44 [net]–47 [net]) связаны с добавлением к дереву новых вершин. Среди этих заданий следует выделить достаточно сложное задание 47 [net], в котором требуется, не изменяя глубины исходного дерева, дополнить его до полного дерева (дерево глубины L называется полным, если все его внутренние вершины имеют по два непосредственных потомка, а все листья находятся на уровне L).

Группа: Tree (преобразование бинарного дерева)
Разбор в классе: 37 [net], 40 [net], 45 [net], 47 [net]
Закрепление материала: 38 [net], 43 [net], 46 [net]
Простые задания: 35 [net], 36 [net], 37 [net], 38 [net], 39 [net]
Сложные задания: 47 [net]
Наборы однотипных заданий: 35 [net]–37 [net]; 38 [net]–39 [net]; 42 [net]–43 [net]; 44 [net]–46 [net]

Бинарные деревья с обратной связью

В данной подгруппе рассматривается вариант представления бинарного дерева, в котором у дочерних вершин имеется поле Parent, связанное с их родительской вершиной. Такие деревья в задачнике называются деревьями с обратной связью.

Первые два задания подгруппы (48 [net]–49 [net]) посвящены знакомству с новым представлением бинарного дерева. Следует обратить внимание на задание 49 [net], в котором требуется преобразовать исходное бинарное дерево в дерево с обратной связью (решение задачи 49 приведено в [7, 8]). В других заданиях подгруппы подобные преобразования выполнять не придется, поскольку все исходные деревья уже имеют обратную связь.

Далее следуют четыре простых задания, в которых по данным вершинам исходного дерева с обратной связью требуется определить какие-либо характеристики этих вершин или дерева в целом: найти корень дерева (50 [net]), уровень данной вершины (51 [net]), «степень родства» (разность уровней) или ближайшего общего предка двух данных вершин (52 [net]–53 [net]). Во всех этих заданиях достаточно использовать итерационные алгоритмы, не прибегая к рекурсии.

Три завершающих задания являются более сложными вариантами ранее рассмотренных заданий на бинарные деревья без обратной связи. В задании 54 [net] требуется создать копию дерева с обратной связью (данное задание аналогично заданию 34 [net]). Задание 55 [net] является «комбинированным» заданием на преобразование дерева с обратной связью, в котором требуется как добавлять новые, так и удалять существующие вершины. Наконец, задание 56 [net] посвящено формированию дерева с обратной связью требуемой глубины (данное задание аналогично заданию 31 [net]).

Группа: Tree (бинарные деревья с обратной связью)
Разбор в классе: 49 [net], 52 [net], 54 [net]
Закрепление материала: 51 [net], 53 [net], 56 [net]
Простые задания: 48 [net], 50 [net], 51 [net]
Сложные задания: 56 [net]
Наборы однотипных заданий: 50 [net]–51 [net]; 52 [net]–53 [net]

Бинарные деревья поиска

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

Понятия дерева поиска и дерева поиска без повторяющихся элементов вводятся в первых двух заданиях подгруппы (57 [net]–58 [net]). В этих заданиях требуется проверить, является ли исходное дерево деревом поиска соответствующего вида, и в случае, если не является, вывести первую (в инфиксном порядке) вершину, нарушающую требуемую закономерность.

Следующие задания (59 [net]–60 [net]) посвящены алгоритмам нахождения требуемых элементов в дереве поиска. Чтобы оценить эффективность этих алгоритмов, в заданиях необходимо вывести не только найденные вершины, но и количество вершин, которые потребовалось проанализировать для выполнения задания (информация о количестве вершин позволяет также проверить, что при поиске действительно был использован эффективный алгоритм, учитывающий специальный вид бинарного дерева).

Задания 61 [net]–64 [net] связаны с алгоритмом добавления нового элемента к дереву поиска (61 [net], 63 [net]) или к дереву поиска без повторяющихся элементов (62 [net], 64 [net]). Поскольку добавить новый элемент к дереву поиска можно различными способами, в заданиях 61 [net]–62 [net] приводится описание того варианта алгоритма, который требуется использовать. Задания 63 [net]–64 [net] являются модификациями предыдущих заданий; в них требуется добавить не один, а несколько элементов с указанными значениями.

Так как при инфиксном переборе элементов дерева поиска его элементы образуют неубывающую последовательность, для сортировки набора чисел достаточно разместить их в дереве поиска, после чего организовать перебор вершин дерева в инфиксном порядке. В этом и заключается идея алгоритма сортировки деревом. Данному виду сортировки посвящены задания 65 [net]–66 [net] (в задании 66 [net] требуется получить отсортированный набор исходных чисел без повторений). В этих заданиях требуется вывести не только отсортированную последовательность чисел, но и использованное в ходе алгоритма дерево поиска; это позволяет проверить, что сортировка действительно была выполнена с помощью дерева. Решение задачи 65 [net] приводится в [7, 8].

Завершающие задания данной подгруппы посвящены алгоритму удаления вершин из дерева поиска. В задании 67 [net] рассматривается вариант алгоритма, который надо использовать в случае, если удаляемая вершина содержит не более одной дочерней вершины. В заданиях 68 [net]–69 [net] рассматриваются два варианта алгоритма, которые можно использовать в случае, если удаляемая вершина содержит две дочерние вершины. Сами алгоритмы приводятся в формулировках заданий. Наконец, в двух последних заданиях (70 [net]–71 [net]) заранее не оговариваются свойства удаляемой вершины, поэтому в них необходимо реализовать полный алгоритм удаления (еще одной особенностью этих двух заданий является то, что обрабатываемое дерево является деревом с обратной связью).

Группа: Tree (бинарные деревья поиска)
Разбор в классе: 58 [net], 59 [net], 61 [net], 65 [net]
Закрепление материала: 57 [net], 60 [net], 62 [net], 66 [net]
Простые задания: 59 [net]
Сложные задания: 57 [net], 58 [net], 65 [net], 66 [net], 67 [net], 68 [net], 69 [net], 70 [net]*, 71 [net]*
Наборы однотипных заданий: 57 [net]–58 [net]; 59 [net]–60 [net]; 61 [net]–62 [net]; 63 [net]–64 [net]; 65 [net]–66 [net]; 68 [net]–69 [net]; 70 [net]–71 [net]

Бинарные деревья разбора выражений

Данная подгруппа дополняет тему, связанную с разбором выражений, которая ранее рассматривалась в разделе «Рекурсия». Под деревом разбора арифметического выражения понимается бинарное дерево, вершины которых соответствуют операндам (в частности, числам) и операциям. При этом вершины, соответствующие операциям, кодируются специальными значениями, например, –1 для операции сложения, –2 для операции вычитания и т. д.

Содержащиеся в подгруппе задания можно отнести к одной из двух категорий. В первую категорию входят задания, в которых требуется по строке-описанию некоторого выражения сформировать дерево разбора этого выражения (72 [net], 74 [net], 76 [net]–78 [net], 83 [net]). Во вторую категорию входят «обратные» задания: в них дается дерево разбора выражения, по которому требуется либо вычислить данное выражение (79 [net], 84 [net]), либо сформировать его строковое описание (73 [net], 75 [net], 80 [net]–82 [net], 85 [net]).

Задания, связанные с формированием дерева разбора выражений, являются достаточно сложными и требуют организации просмотра исходного строкового выражения и его анализа с применением вспомогательных рекурсивных подпрограмм. Указанные действия следует выполнять по схеме, аналогичной той, которая была использована для заданий на разбор выражений из группы Recur. В [7, 8] приведено подробное решение задания 74 [net], являющееся «модельным» для всех заданий данной категории.

Задания, связанные с использованием данного дерева разбора, являются более простыми; в них достаточно организовать перебор вершин дерева в требуемом порядке, заполняя при этом требуемую строку-описание для соответствующего выражения или вычисляя его значение. В [7, 8] приведено решение одного из таких заданий (75 [net]), прочие задания выполняются аналогично.

В заданиях рассматриваются три вида выражений:

  • выражения, описывающие бинарное дерево (72 [net]–75 [net]);
  • арифметические выражения, включающие цифры и операции сложения, вычитания и умножения (76 [net]–82 [net]);
  • выражения, содержащие цифры и вызовы функций M(x,y) и m(x,y), возвращающих соответственно максимальное и минимальное из чисел x и y (83 [net]–85 [net]).

В заданиях 72 [net]–75 [net] используются два варианта описания бинарных деревьев. В более простом варианте (задания 72 [net]–73 [net]) все вершины описываются единообразно, независимо от количества их непосредственных потомков, например, «4(2(,),6(,7(3(,),)))». В скобках вначале указывается значение левой дочерней вершины, а затем — правой (при условии, что они существуют). В более сложном варианте (задания 74 [net]–75 [net]) описание вершины зависит от числа ее непосредственных потомков, например, «4(2,6(,7(3)))». В этом варианте при описании листьев скобки не используются; кроме того, при отсутствии правой дочерней вершины запятая также не указывается.

При описании арифметических выражений применяются либо скобки, явно определяющие порядок выполнения операций (задания 76 [net], 79 [net]–80 [net]), либо бесскобочные форматы: префиксный (77 [net], 81 [net]) и постфиксный (78 [net], 82 [net]).

Группа: Tree (бинарные деревья разбора выражений)
Разбор в классе: 74 [net], 75 [net], 77 [net], 81 [net]
Закрепление материала: 72 [net], 73 [net], 78 [net], 82 [net]
Простые задания: нет
Сложные задания: 72 [net], 74 [net]
Наборы однотипных заданий: 76 [net]–78 [net]; 79 [net]–82 [net]

Деревья общего вида

В завершающей подгруппе группы Tree рассматриваются деревья с произвольным ветвлением, т. е. деревья, вершины которых могут содержать произвольное число непосредственных потомков. Для краткости в формулировках заданий такие деревья называются деревьями общего вида. Деревья общего вида моделируются «обычными» бинарными деревьями, связи в которых интерпретируются особым образом: ссылка Left для любой вершины N указывает на ее первую дочернюю вершину, а ссылка Right — на ее правую сестру, т. е. вершину, имеющую того же родителя, что и вершина N. Таким образом, данная структура содержит как иерархические компоненты типа «предок–потомок» (по ссылкам Left), так и линейные компоненты — односвязные списки «сестер» (по ссылкам Right).

При выполнении заданий из данной подгруппы важно учитывать особенности интерпретации ссылок Left и Right для деревьев общего вида. Чтобы облегчить эту задачу, в электронном задачнике Programming Taskbook используются различные визуальные представления «обычных» бинарных деревьев и деревьев общего вида.

Как обычно, начальные задания подгруппы (86 [net]–87 [net]) вводят новые понятия и связывают их с ранее изученными. В задании 86 [net] требуется преобразовать исходное бинарное дерево в дерево общего вида (при этом будет потеряна часть информации, поскольку в дереве общего вида нельзя по единственному потомку определить, является ли он левой или правой дочерней вершиной). Задание 87 [net] посвящено обратному преобразованию дерева общего вида, все вершины которого имеют не более двух непосредственных потомков, в «обычное» бинарное дерево (здесь предполагается, что единственный потомок является левой дочерней вершиной). Решение задачи 86 [net] приводится в [7, 8].

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

  • анализ дерева общего вида, в том числе нахождение его глубины (задание 88 [net] — ср. с заданием 9 [net]), анализ вершин по уровням (89 [net]–91 [net] — ср. с 10 [net]–11 [net]), перебор всех вершин в требуемом порядке (92 [net]–93 [net] — ср. с 12 [net]–14 [net]), поиск вершины с требуемым количеством дочерних вершин (94 [net]–96 [net]);
  • преобразование дерева общего вида путем изменения значений дочерних вершин (97 [net]–98 [net]);
  • работа с выражениями, описывающими дерево общего вида, в том числе создание дерева общего вида по его описанию (99 [net]) и формирование такого описания по исходному дереву (100 [net]).

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

Группа: Tree (деревья общего вида)
Разбор в классе: 86 [net], 88 [net], 92 [net], 95 [net], 97 [net]
Закрепление материала: 87 [net], 89 [net], 93 [net], 96 [net], 98 [net]
Простые задания: нет
Сложные задания: 99 [net]
Наборы однотипных заданий: 89 [net]–90 [net]; 92 [net]–93 [net]; 94 [net]–96 [net]; 97 [net]–98 [net]


Указания

Задачи, связанные с ЕГЭ по информатике

Начиная с версии 4.10 электронного задачника, в базовый набор его заданий входят группы ExamBegin и ExamTaskC, связанные с ЕГЭ по информатике [9]. Особенность этих групп заключается в другом способе организации ввода-вывода (по сравнению с вводом-выводом, используемым при выполнении заданий из других групп задачника). Если для «обычных» групп для ввода и вывода данных необходимо использовать специальные процедуры задачника (или специальный поток ввода-вывода в языке C++), то для групп Exam ввод и вывод надо организовывать с применением стандартных средств используемого языка программирования (процедур Read–Write для языка Pascal, стандартных потоков cin–cout для языка C++). При этом программа учащегося должна сама обеспечивать форматирование выводимых данных (в заданиях других групп это не требуется, так как действия по наглядному отображению полученных данных задачник выполняет самостоятельно). Отмеченные особенности заданий групп Exam позволяют максимально приблизить вид программы, выполняющей задание, к виду, требуемому на экзамене. При этом сохраняются основные особенности электронного задачника, делающие процесс выполнения заданий более быстрым и эффективным: генерация наборов исходных данных и автоматическая проверка правильности решения. Выполнять задания групп Exam с применением электронного задачника можно только на языках Pascal и C++.

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

Базовые алгоритмы: группа ExamBegin

[Перейти к формулировкам] [Перейти к началу раздела «Группы заданий»] [Перейти к началу раздела «Указания»]

Группу ExamBegin, содержащую 100 заданий, можно рассматривать как сокращенный набор заданий по основным разделам базового курса программирования (до массивов и строк включительно). При отборе заданий для включения в эту группу принимался во внимание кодификатор ЕГЭ по информатике и ИКТ [21]. Все алгоритмические задачи, упомянутые в кодификаторе, с той или иной степенью полноты отражены в группе ExamBegin. Ниже приводится перечень задач из кодификатора с указанием номеров соответствующих заданий группы ExamBegin:

  • нахождение минимума и максимума двух, трех, четырех данных чисел без использования массивов и циклов: 1–3;
  • нахождение всех корней заданного квадратного уравнения: 4;
  • нахождение наибольшего общего делителя двух натуральных чисел (алгоритм Евклида): 5–6;
  • запись натурального числа в позиционной системе с основанием меньшим или равным 10, обработка и преобразование такой записи числа: 7–8;
  • нахождение сумм, произведений элементов данной конечной числовой последовательности (или массива): 14–17;
  • использование цикла для решения простых переборных задач (поиск наименьшего простого делителя данного натурального числа, проверка числа на простоту и т. д.): 9–13;
  • заполнение элементов одномерного и двумерного массива по заданным правилам: 18–29;
  • операции с элементами массива (линейный поиск элемента, вставка и удаление элементов в массиве, перестановка элементов данного массива в обратном порядке, суммирование элементов массива, проверка соответствия элементов массива некоторому условию): 30–33, 69–82;
  • нахождение минимального (максимального) значения в данном массиве и количества элементов, равных ему, за однократный просмотр массива: 45–47, 51–52, 57–58;
  • нахождение второго по величине (второго максимального или второго минимального) значения в данном массиве за однократный просмотр массива: 53–54;
  • операции с элементами массива, отобранными по некоторому условию (например, нахождение минимального четного элемента в массиве, нахождение количества и суммы всех четных элементов в массиве): 34–44, 48–50, 55–56, 59–68;
  • сортировка массива: 83;
  • слияние двух упорядоченных массивов в один без использования сортировки: 84;
  • обработка отдельных символов данной строки, подсчет частоты появления символа в строке: 85–90;
  • работа с подстроками данной строки, в том числе разбиение строки на слова по пробельным символам, поиск подстроки внутри данной строки, замена найденной подстроки на другую строку: 91–100.

Многие из заданий группы ExamBegin являются переформулировками заданий из групп If, For, While, Series, Minmax, Array, Matrix, String, поэтому группу ExamBegin можно использовать на проверочных работах по соответствующим темам, а также при проведении итогового повторения.

Группа: ExamBegin (условные операторы и циклы)
Разбор в классе: 2, 5, 7, 12, 14
Закрепление материала: 1, 3, 6, 8, 13, 15
Простые задания: 1, 4, 11, 14, 15
Сложные задания: 7, 8, 13
Наборы однотипных заданий: 1–3; 5–6; 9–11; 14–15; 16–17
Группа: ExamBegin (формирование массивов)
Разбор в классе: 21, 28
Закрепление материала: 20, 29
Простые задания: 18, 19
Сложные задания: 28, 29
Наборы однотипных заданий: 20–21; 24–25; 26–27; 28–29
Группа: ExamBegin (анализ одномерных массивов) Разбор в классе: 33, 38, 42
Закрепление материала: 34, 37, 39, 43, 44
Простые задания: 30
Сложные задания: 40, 41
Наборы однотипных заданий: 31–32; 33–34; 35–36; 37–39; 42–44
Группа: ExamBegin (минимумы и максимумы)
Разбор в классе: 45, 49, 51, 53
Закрепление материала: 46, 48, 52, 54
Простые задания: 45, 46, 47
Сложные задания: 53, 54, 55, 56
Наборы однотипных заданий: 46–47; 48–50; 53–54; 55–56; 57–58
Группа: ExamBegin (анализ двумерных массивов)
Разбор в классе: 61, 65
Закрепление материала: 60, 64
Простые задания: 59
Сложные задания: 68
Наборы однотипных заданий: 60–61; 62–63; 64–65; 66–67
Группа: ExamBegin (преобразование массивов)
Разбор в классе: 71, 73, 78, 83, 84
Закрепление материала: 74, 79, 80
Простые задания: 69, 70
Сложные задания: 75, 76
Наборы однотипных заданий: 69–70; 77–78, 79–80
Группа: ExamBegin (обработка текстовых данных)
Разбор в классе: 87, 91, 95
Закрепление материала: 86, 92, 96
Простые задания: 85, 86
Сложные задания: 99, 100
Наборы однотипных заданий: 85–86; 94–97; 99–100

Задачи повышенной сложности: группа ExamTaskC

[Перейти к формулировкам] [Перейти к началу раздела «Группы заданий»] [Перейти к началу раздела «Указания»]

В группу ExamTaskC включены задачи повышенного уровня сложности, подобные задачам С4 ЕГЭ по информатике. Основная часть задач посвящена обработке сложных наборов данных (записей) с элементами-полями различных типов. В подобных задачах требуется правильно выбрать способ хранения данных и организовать их эффективную обработку; при этом обычно требуется применить несколько базовых алгоритмов, например, алгоритм суммирования или нахождения минимума/максимума и алгоритм поиска нужного элемента или сортировки набора данных по требуемому ключу.

Задачи разбиты на серии; каждая серия имеет общую предметную область и характеризуется рядом особенностей наборов данных и алгоритмов их обработки. Во всех заданиях одной серии исходный набор содержит одинаковые поля, однако порядок следования полей в разных заданиях серии различается.

Во всех заданиях (кроме начальных заданий 1–6) требуется выполнять сортировку полученных данных, хотя в некоторых случаях можно обойтись без применения алгоритма сортировки за счет подходящей индексации массивов, в которых хранятся результирующие данные. Во многих случаях требуется выполнять сортировку по набору ключей. Для большинства заданий, в которых требуется вывести набор результирующих записей, предусматривается «парное» задание, в котором необходимо вывести тот же набор записей, однако отсортированный по другому ключу (набору ключей).

Ниже приводятся краткие описания каждой из 6 серий заданий.

«Клиенты фитнес-центра»: задания 1–24.

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

Отсутствие строковых данных упрощает организацию ввода этих наборов. В заданиях 1–6, в отличие от остальных заданий на обработку сложных наборов данных, требуется определить единственный элемент исходного набора с нужным свойством. В прочих заданиях требуется выполнять группировку записей по какому-либо полю (или по паре полей «год–месяц» в заданиях 19–22) и обрабатывать нужным образом каждый элемент полученной группировки.

Группа: ExamTaskC («Клиенты фитнес-центра»)
Разбор в классе: 1, 4, 13, 19
Закрепление материала: 2, 3, 14, 21
Простые задания: 1, 2, 3, 4, 5, 6
Сложные задания: 19, 20, 21, 22
Наборы однотипных заданий: 1–2, 3–4, 5–6, 7–10, 11–12, 13–18, 19–22, 23–24

«Абитуриенты»: задания 25–36.

Исходные наборы содержат следующие поля: номер школы, год поступления в вуз, фамилия.

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

Группа: ExamTaskC («Абитуриенты»)
Разбор в классе: 25, 34
Закрепление материала: 27, 31
Простые задания: 25, 26
Сложные задания: 35, 36
Наборы однотипных заданий: 25–28; 29–30; 31–34; 35–36

«Задолжники по коммунальным платежам»: задания 37–48.

Исходные наборы содержат следующие поля: номер квартиры, фамилия, размер задолженности.

В этих заданиях присутствуют строковые данные (фамилия) и числовые данные вещественного типа (размер задолженности в рублях и копейках), причем, в отличие от предыдущей серии, в задании требуется анализировать все данные, в том числе и строковые. Дополнительная сложность этих заданий обусловлена необходимостью группировки исходных данных по этажам или по подъездам дома (по условию дом имеет 4 подъезда и 9 этажей, по 4 квартиры на каждом этаже в каждом подъезде).

Группа: ExamTaskC («Задолжники по коммунальным платежам»)
Разбор в классе: 37, 44
Закрепление материала: 38, 43
Простые задания: 37, 38, 39, 40
Сложные задания: 47, 48
Наборы однотипных заданий: 37–40; 41–44; 45–46; 47–48

«Автозаправочные станции»: задания 49–60.

Исходные наборы содержат следующие поля: компания, марка бензина, цена 1 литра (в копейках), улица.

Значение марки бензина может быть равно 92, 95, 98. Поля «компания» и «улица» могут принимать строковые значения из некоторого множества строк (количество вариантов названий компаний и улиц фиксировано и указывается в задании). В этой серии заданий, в отличие от предыдущих, требуется выполнять группировку исходных данных по строковым полям.

Группа: ExamTaskC («Автозаправочные станции»)
Разбор в классе: 49, 53
Закрепление материала: 50, 54
Простые задания: 49, 50
Сложные задания: 57*, 58*, 59*, 60*
Наборы однотипных заданий: 49–50; 51–54; 55–56; 57–58; 59–60

«Баллы ЕГЭ»: задания 61–72.

Исходные наборы содержат следующие поля: фамилия, инициалы, баллы ЕГЭ (три целых числа), номер школы.

Первой особенностью данной серии является наличие двух полей, которые необходимо всегда обрабатывать совместно (фамилия и инициалы), и поэтому требуется организовать считывание этих полей в одну строковую переменную. Второй особенностью является наличие составного поля «баллы ЕГЭ», для хранения которого следует использовать массив.

Группа: ExamTaskC («Баллы ЕГЭ»)
Разбор в классе: 62, 68
Закрепление материала: 61, 67
Простые задания: 61
Сложные задания: 69, 70, 71, 72
Наборы однотипных заданий: 63–64; 65–66; 67–68; 69–70; 71–72

«Оценки по предметам»: задания 73–82.

Исходные наборы содержат следующие поля: фамилия, инициалы, номер класса, название предмета, оценка.

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

Группа: ExamTaskC («Оценки по предметам»)
Разбор в классе: 73, 81
Закрепление материала: 74, 79
Простые задания: нет
Сложные задания: 77, 78, 79*, 80*, 81*, 82*
Наборы однотипных заданий: 73–74; 75–76; 77–78; 79–82

В группу ExamTaskC включены также задания на обработку текстовых данных. В эту подгруппу входят задания следующих типов:

  • выделение и анализ цифровых символов, в том числе преобразование отдельных цифровых символов или набора соседних цифровых символов в числа (83–85);
  • составление из имеющихся цифровых символов строковых представлений чисел, обладающих дополнительными свойствами, в том числе чисел-палиндромов (86–90);
  • шифрование исходного набора строк с использованием различных вариантов замен буквенных символов (91–96);
  • обработка символов, содержащегося в исходных строковых наборах; в частности, определение набора символов, встречающихся в тексте, и нахождение числа повторений каждого символа (97–100).
Группа: ExamTaskC (обработка текстовых данных)
Разбор в классе: 83, 86, 88, 92, 97, 100
Закрепление материала: 84, 87, 89, 93, 98, 99
Простые задания: 83, 86, 97, 98
Сложные задания: 85, 88, 89, 90, 94*, 95*, 96*, 100
Наборы однотипных заданий: 86–87; 89–90; 91–93; 94–96; 97–98


Литература

[Перейти к предисловию] [Перейти к началу раздела «Группы заданий»] [Перейти к началу раздела «Указания»]

  1. Абрамян А. В., Абрамян М. Э. Практикум по программированию на языке Visual Basic. — Ростов н/Д: «ЦВВР», 2007. — 228 с.
  2. Абрамян А. В., Абрамян М. Э. Использование базового набора заданий электронного задачника Programming Taskbook при проведении практических занятий. — Банк компьютерных изданий ЮФУ, 2011. — 85 с. URL: http://open-edu.sfedu.ru/files/abramyan_pttasks.pdf.
  3. Абрамян М. Э. 1000 задач по программированию. Части I–III. — Ростов н/Д: УПЛ РГУ, 2004. — 128 с.
  4. Абрамян М. Э. Проведение практических занятий с использованием задачника Programming Taskbook. Методическая разработка для преподавателей программирования. — Банк компьютерных изданий РГУ, 2006. — 83 с. URL: http://open-edu.rsu.ru/upload/pub/37607100_1149508000Archive.zip.
  5. Абрамян М. Э. Практикум по программированию на языках C# и VB .NET. 2-е изд. — Ростов н/Д: «ЦВВР», 2007. — 220 с.
  6. Абрамян М. Э. Конструктор учебных заданий для электронного задачника Programming Taskbook. Методическая разработка для преподавателей программирования. — Банк компьютерных изданий ЮФУ, 2009. — 76 с. URL: http://open-edu.sfedu.ru/files/abramyan_taskmaker.pdf.
  7. Абрамян М. Э. Бинарные деревья: Задачи, решения, указания. — Банк компьютерных изданий ЮФУ, 2009. — 71 с. URL: http://open-edu.sfedu.ru/files/abramyan-bintrees.zip.
  8. Абрамян М. Э. Практикум по программированию на языке Паскаль: Массивы, строки, файлы, рекурсия, линейные динамические структуры, бинарные деревья. 7-е изд., перераб. и доп. — Ростов н/Д: Изд-во ЮФУ, 2010. — 276 с.
  9. Абрамян М. Э. Подготовка к ЕГЭ по информатике с использованием электронного задачника Programming Taskbook. — Ростов н/Д: Изд-во ЮФУ, 2011. — 100 с.
  10. Абрамян М. Э., Михалкович С. С. Основы программирования на языке Паскаль: Скалярные типы данных, управляющие операторы, процедуры и функции, работа с графикой в системе PascalABC.NET. 5-е изд. — Ростов н/Д: «ЦВВР», 2009. — 223 с.
  11. Абрамов С. А., Гнездилова Г. Г., Капустина Е. Н., Селюн М. И. Задачи по программированию. — М.: Наука, 1988. — 224 с.
  12. Амелина Н. И., Королева Е. М. Методические указания для студентов механико-математического факультета «Задачи по программированию». Часть 2. — Ростов н/Д: УПЛ РГУ, 1993. — 31 с.
  13. Бабушкина И. А., Бушмелева Н. А., Окулов С. М., Черных С. Ю. Практикум по Турбо Паскалю. — М.: АБФ, 1998. — 384 с.
  14. Гусева А. И. Учимся программировать: PASCAL 7.0. Задачи и методы их решения. — М.: Диалог-МИФИ, 1997. — 256 с.
  15. Дагене В. А., Григас Г. К., Аугутис К. Ф. 100 задач по программированию. — М.: Просвещение, 1993. — 255 с.
  16. Демонстрационный вариант контрольных измерительных материалов 2011 года по информатике и ИКТ. URL: http://www1.ege.edu.ru/.
  17. Демонстрационный вариант контрольных измерительных материалов единого государственного экзамена 2012 года по информатике и ИКТ. URL: http://www1.ege.edu.ru/.
  18. Задачи по программированию / С. М. Окулов, Т. В. Ашихмина, Н. А. Бушмелева и др.; Под ред. С. М. Окулова. — М.: БИНОМ. Лаборатория знаний, 2006. — 820 с.
  19. Златопольский Д. М. Я иду на урок информатики: Задачи по программированию. 7-11 классы: Книга для учителя. — М.: «Первое сентября», 2001. — 208 с.
  20. Касьянов В. Н., Сабельфельд В. К. Сборник заданий по практикуму на ЭВМ. — М.: Наука, 1986. — 272 с.
  21. Кодификатор элементов содержания и требований к уровню подготовки выпускников общеобразовательных учреждений для проведения в 2012 году единого государственного экзамена по информатике и ИКТ. URL: http://www1.ege.edu.ru/.
  22. Михалкович С. С. Основы программирования: Динамические массивы. Списки. Ассоциативные массивы. Деревья. Хеш-таблицы. — Ростов н/Д: УПЛ ЮФУ, 2007. — 48 с.
  23. Пильщиков В. Н. Сборник упражнений по языку Паскаль. — М.: Наука, 1989. — 160 с.
  24. Программирование на языке Паскаль: задачник / Под ред. О. Ф. Усковой. — СПб.: Питер, 2002. — 336 с.
  25. Юркин А. Г. Задачник по программированию. — СПб.: Питер, 2002. — 192 с.