e-olymp 2270. Поиск цикла

Задача

Дан ориентированный невзвешенный граф. Необходимо определить есть ли в нём циклы, и если есть, то вывести любой из них.

Входные данные

В первой строке находятся два натуральных числа $n$ и $m$ $($$1$ $\leqslant$ $n$ $\leqslant$ $10$$5$$, $$1$ $\leqslant$ $m$ $\leqslant$ $10$$5$$)$ — количество вершин и ребер в графе соответственно. Далее в $m$ строках перечислены рёбра графа. Каждое задаётся парой чисел — номерами начальной и конечной вершин соответственно.

Выходные данные

Если в графе нет цикла, то вывести «NO», иначе вывести «YES» и затем перечислить вершины в порядке обхода цикла.

Тесты

Входные данные

Выходные данные

1
2 2
1 2
1 2
NO
2 2 2
1 2
2 1
YES
1 2
3 6 7
1 2
1 5
2 3
2 4
4 6
6 5
5 2
YES
2 4 6 5
4 6 6
1 3
2 4
3 4
1 2
3 5
3 6
NO
5 4 4
1 3
4 2
2 3
3 4
YES
3 4 2

Решение

Для решения данной задачи воспользуемся поиском в глубину. Также будем отмечать вершины в различными цветами ($0$ (белый) — мы еще не посещали вершину, $1$ (серый) — посетили вершину и не вышли из нее (зациклились), $2$ (черный) — посетили вершину и вышли из неё).

В векторе $graph$ будем хранить сам граф, для проверки на цикличность воспользуемся вектором $visited$, так же будем хранить порядок обхода графа в векторе $path$. Так как по условию, в случае нескольких циклов, необходимо вывести любой, то мы будем находить первый и на этом останавливаться, для этого заведем переменную $flag$, которая равна 1, если цикл уже найден, и равна 0, если цикл еще не найден. В векторе $visited$ будем окрашивать вершину в один из цветов. Если мы захотим посетить $1$ (серую) вершину, то это будет означать, что мы отыскали цикл в этой вершине, тогда устанавливаем $flag = 1$.

Осталось лишь вывести его на экран. Для этого воспользуемся вектором $path$, в котором последний элемент — вершина, в которой цикл. Ищем предпоследнее вхождение этой вершины в векторе $path$ и выводим сам цикл.

Ссылки

Условие задачи на e-olymp

Код программы на ideone

e-olymp 1872. Снеговики

Задача

Зима. 2012 год. На фоне грядущего Апокалипсиса и конца света незамеченной прошла новость об очередном прорыве в областях клонирования и снеговиков: клонирования снеговиков. Вы конечно знаете, но мы вам напомним, что снеговик состоит из нуля или более вертикально поставленных друг на друга шаров, а клонирование — это процесс создания идентичной копии (клона).

В местечке Местячково учитель Андрей Сергеевич Учитель купил через интернет-магазин «Интернет-магазин аппаратов клонирования» аппарат для клонирования снеговиков. Теперь дети могут играть и даже играют во дворе в следующую игру. Время от времени один из них выбирает понравившегося снеговика, клонирует его и:

  • либо добавляет ему сверху один шар;
  • либо удаляет из него верхний шар (если снеговик не пустой).

Учитель Андрей Сергеевич Учитель записал последовательность действий и теперь хочет узнать суммарную массу всех построенных снеговиков.

Входные данные

Первая строка содержит количество действий $n (1 ≤ n ≤ 200000)$. В строке номер $i + 1$ содержится описание действия:

  • $t m$ — клонировать снеговика номер $t (0 ≤ t < i)$ и добавить сверху шар массой $m (0 < m ≤ 1000)$;
  • $t 0$ — клонировать снеговика номер $t (0 ≤ t < i)$ и удалить верхний шар. Гарантируется, что снеговик не пустой.

В результате действия $i$, описанного в строке $i + 1$ создается снеговик номер $i$. Изначально имеется пустой снеговик с номером ноль.

Все входные числа целые.

Выходные данные

Выведите суммарную массу построенных снеговиков.

Тесты

Входные данные Выходные данные
8
0 1
1 5
2 4
3 2
4 3
5 0
6 6
1 0
74
4
0 3
1 2
2 1
1 1
18
2
0 1
1 5
7
5
1 2
3 4
5 5
1 7
5 6
26

Код задачи

 

Решение задачи

Считываем n  — количество действий. Задаем двухмерный массив размером [n+1][2] . Указываем значение первого элемента равное $0$ и нулевого элемента равного $-1$, чтобы он ни на что не ссылался в начале.  В цикле считываем номер снеговика, которого нужно клонировать и массу шара, которую нужно добавить. Если масса шара равна $0$, то мы клонируем снеговика и убираем последний его шар, ссылаясь на снеговика в котором этого шара еще не было. Если же масса шара не равно $0$, то мы клонируем снеговика и добавляем ему шар массой $m$. Во второй ячейке указываем предка с которого строится новый снеговик. Выводим общую массу снеговиков.

Ссылки

Условие задачи на e-olymp.com
Решение задачи на ideone.com

e-olymp 1228. Добавить все

Условие

Условие задачи отражает Вашу задачу: необходимо просто сложить числа. Но это будет унизительно если Вас попросят просто написать такую программу на языке C/C++ для заданного множества чисел. Давайте внесем в задачу оттенок изобретательности.

Введем понятие стоимости для операции сложения. Стоимость сложения двух чисел положим равным их сумме. Например, сложить числа $1$ и $10$ стоит $11$. Стоимость сложения $1,2$ равна $3$. Складывать числа можно разными способами:

  1. $1 + 2 = 3$ (стоимость = 3), $3 + 3 = 6$ (стоимость = 6), Всего = 9
  2. $1 + 3 = 4$ (стоимость = 4), $2 + 4 = 6$ (стоимость = 6), Всего = 10
  3. $2 + 3 = 5$ (стоимость = 5), $1 + 5 = 6$ (стоимость = 6), Всего = 11

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

Входные данные

Начинаются целым числом $n (2 \leq n \leq 100000)$, за которым следуют $n$ целых неотрицательных чисел (все числа меньше $100000$).

Выходные данные

Вывести наименьшую стоимость сложения всех чисел.

Тесты

Входные данные Выходные данные
$4$
$10$ $12$ $13$ $11$
$92$
$5$
$100$ $11$ $8$ $30$ $12$
$272$
$4$
$2$ $2$ $2$ $2$
$16$
$6$
$1$ $2$ $3$ $4$ $5$ $6$
$51$

Код решения

Решение

Стоимость сложения всех чисел будет минимальной, если на каждом следующем шаге мы будем складывать два наименьшие числа из множества $A$, состоящего из данного ряда чисел и уже вычисленных «частичных сумм». Таким образом, каждый шаг цикла поиска минимальной стоимости сложения будет состоять из нахождения двух минимальных чисел из множества, удаления этих чисел из множества $A$ и добавления в него результата их суммирования. В специальную переменную $minSum$ будем также каждый раз добавлять результат этого суммирования. Таким образом, количество элементов во множестве будет с каждым шагом уменьшаться на одно, и в конце, когда в нем останется единственный элемент, переменная $minSum$ будет содержать искомую стоимость сложения всех чисел.
Реализовать такой код достаточно просто, если реализовать множество $A$ в виде очереди с приоритетом.

Ссылки

Условие задачи на e-olymp.com
Код решения на ideone.com

e-olymp 4475. Часы

Задача

Жители планеты Олимпия любят летать в гости на другие планеты. Ученые планеты разработали часы, которые могут налаживаться для отсчета времени на любой планете. Эти часы состоят из шариков, лотка (очереди) и трех чаш: секундной, минутной и часовой. В каждый момент времени количество шариков в чашах показывает время (секунды, минуты и часы соответственно). Каждую секунду первый шарик из очереди попадает в секундную чашу. Если секундная чаша наполнилась (количество шариков равно количеству секунд в минуте на этой планете), то этот шарик переходит в минутную чашу, а остальные шарики переходят из секундной чаши в конец очереди в порядке, обратном к их попаданию в секундную чашу. Аналогично, при наполнении минутной чаши последний шарик переходит в часовую чашу, а остальные шарики из минутной чаши переходят в конец очереди в порядке, обратном к их попаданию в минутную чашу. Если заполняется часовая чаша, то все шарики из нее переходят в конец очереди в порядке, обратном к их попаданию в часовую чашу. Все шарики пронумерованы и в начальный момент времени находятся в очереди.

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

Входные данные

Входной файл содержит в единственной строке натуральные числа $S, M, H, K$ (количество секунд в минуте, минут в часе, часов в сутках и общее количество шариков соответственно), причем:

  • $S, M, H ≤ 60$;
  • $S+M+H-2≤K≤1000$

Выходные данные

Выходной файл должен содержать в единственной строке вычисленное Вашей программой количество суток.

Тесты

Входные данные Выходные данные
$5$ $12$ $12$ $30$ $380$
$7$ $10$ $40$ $70$ $5610$
$60$ $60$ $60$ $500$ $4560840$
$60$ $30$ $5$ $1000$ $4970$

Код программы

Алгоритм решения

  1. Интуитивно понятно, что положение шариков в очереди ежесуточно изменяется по одному и тому же закону, в силу однообразия процесса. Отыскать конкретный вид перестановки можно прямым моделированием часов, используя дек для описания лотка и стеки — каждой из чаш (у очереди задействованы оба конца, у чаш — только один).
  2. Определить порядок суточной перестановки можно и возведением её в степень, но это нерациональный способ. Используя теорему о разложении перестановки в композицию циклов (к слову, непересекающихся), можно заметить, что порядок каждого из циклов равен его длине. Если мысленно представить перестановку в виде ориентированного графа, то процесс поиска циклов сведётся к поиску в глубину: обойти каждую компоненту связности, зафиксировать число входящих в неё вершин (на илл.)
    $\begin{pmatrix}
    1& 2& 3& 4& 5& 6& 7& 8& 9& 10\\
    1& 5& 8& 2& 4& 3& 7& 7& 6& 10
    \end{pmatrix}$
    permutations in group
  3. Зная длины всех циклов, нетрудно заметить, что задача сводится к поиску НОК полученной последовательности длин. Обосновать такой переход можно индуктивно: порядок перестановки, представимой в виде композиции двух циклов, равен НОК их длин, а случай большего количества циклов в разложении сводится к рассмотренному последовательным рассмотрением пар циклов (результат не зависит от порядка рассмотрения в силу ассоциативности композиции).

Примечание

Операция взятия остатка для чисел с плавающей точкой не определена аппаратно, так что алгоритм Евклида вычисления НОД реализован в соответствии с его математическим описанием.

Ссылки

Условие задачи на e-olymp
Код решения

A281 Последовательные вычисления значений нового массива

Условие задачи:
Даны действительные числа [latex]a_{1}, \ldots, a_{n}, b_{1}, \ldots, b_{n}[/latex]. Члены последовательности [latex]c_{1}, \ldots, c_{n+1}[/latex] связаны с членами данных последовательностей соотношениями [latex]c_{n+1}=0, c_{\left (n+1\right )-i}=\frac{a_{\left (n+1\right )-i}}{b_{\left (n+1\right )-i}-c_{\left (n+1\right )-i+1}} \left (i=1, \ldots, n \right ).[/latex] Получить [latex]c_{1}, \ldots, c_{n+1}[/latex].

Входные данные:
В первой строке задано число [latex]n[/latex]. В последующих строках записано две числовые последовательности из n чисел.

Выходные данные:
Вывести результирующую последовательность [latex]c[/latex], найденную согласно условию задачи.

Тесты:

Входные данные Выходные данные
28 100 23 45 62 17 873 46 927 64 5 8 9 3 0 89 73 12 53 62 7 12 35 64 50 227 23 100 80
12 34 23 6 7 8 9 25 10 9 73 24 27 8 4 3 2 0 9 1 45 62 100 104 5 6 14 21
8.89145197864941 0.7532429753739995 3.46536409638595 10.014351523139867 -0.19111480725820545
95.9517680178081 -1.0983211464949347 50.88210356032888 6.781413598577088 0.5624396639914702
0.11015755091584475 0.3767441860465116 0.1111111111111111 0.0 4.803215151847447 -14.529255339679752
8.024345590557227 0.5045509487875016 -105.04390117066583 9.590229411789153 0.2700904535823736
0.5704400476332376 0.6438589905891021 0.5993533748082496 20.57676071984004 -6.031862745098037
9.813084112149534 3.8095238095238093 0.0
10 2 -4 1 2 45.2 34 -23 34 56 7.09
-3.4 4 4 -5 2.4 34.04 23 567 -3 4
-0.8567913942992066 -1.0657095142326265 0.24663198875517678 -0.05462407795229777 31.61389033873605 0.9702487256173882 -1.0025608427005548 0.05874893533055214 -11.733892090099529 1.7725 0.0

Код программы:

Алгоритм решения:
Узнаем количество необходимых элементов: считаем число [latex]n[/latex]. С помощью двух циклов также считаем все элементы массивов [latex]a[/latex] и [latex]b[/latex]. Заведем еще один счетчик для нахождения значений ячеек нового массива, воспользовавшись нашей заданной формулой [latex]c_{\left (n+1\right )-i}=\frac{a_{\left (n+1\right )-i}}{b_{\left (n+1\right )-i}-c_{\left (n+1\right )-i+1}} \left (i=1, \ldots, n \right )[/latex] при условии, что [latex]c_{n+1}=0.[/latex] Выведем все элементы единой строкой.

Код программы на Java
Условие задачи

e-olymp 5741. Стек шаров

Задание

Телеканал XYZ разрабатывает новое игровое шоу, в котором участники должны сделать некоторый выбор чтобы получить приз. Игра состоит из треугольного стека шаров, на каждом из которых записано целочисленное значение, как показано ниже на примере.

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

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

Входные данные

Каждый тест задается в нескольких строках. Первая строка содержит количество рядов [latex]N (1 ≤ N ≤ 1000)[/latex] в стеке. [latex]i[/latex]-ая из следующих [latex]N [/latex] строксодержит [latex]i[/latex] целых чисел [latex]B_{ij} (-10^{5}≤ B_{ij}≤ 10^{5}[/latex] для [latex]1 ≤ j ≤ i ≤ N)[/latex]; значение [latex]B_{ij}[/latex] равно числу, записанному на [latex]j[/latex]-ом шаре в [latex]i[/latex]-ом ряду стека (первый ряд — самый верхний, в каждом ряду первым шаром является самый левый).

За последним тестом следует строка, содержащая один ноль.

Выходные данные

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

Тесты

Ввод Вывод
4
3
-5 3
-8 2 -8
3 9 -2 7
2
-2
1 -10
3
1
-5 3
6 -4 1
0
7
0
6
3
7
2 1
3 4 6
2
5
9 2
1
2
0
23
16
2

Код

Решение

Иницианилизируем  двумерный массив [latex]s[/latex], который будет играть роль нашего стека. При считывании массива будем сразу суммировать предыдущие шары. Далее будем хранить в нижних шарах стека сумму всех верхних и при обходе с помощью максимума находить оптимальный путь. Остаётся только найти максимум среди получившихся сумм. Это и будет нашим ответом.

Ссылки

  1. Условие на e-olymp
  2. Код на Ideone

e-olymp 6129. Дек с защитой от ошибок

Задача с сайта e-olymp.com.

Условие задачи

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

push_front

Добавить (положить) в начало дека новый элемент. Программа должна вывести ok.

push_back

Добавить (положить) в конец дека новый элемент. Программа должна вывести ok.

pop_front

Извлечь из дека первый элемент. Программа должна вывести его значение.

pop_back

Извлечь из дека последний элемент. Программа должна вывести его значение.

front

Узнать значение первого элемента (не удаляя его). Программа должна вывести его значение.

back

Узнать значение последнего элемента (не удаляя его). Программа должна вывести его значение.

size

Вывести количество элементов в деке.

clear

Очистить дек (удалить из него все элементы) и вывести ok.

exit

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

Гарантируется, что количество элементов в деке в любой момент не превосходит 100. Перед исполнением операций pop_front, pop_back, front, back программа должна проверять, содержится ли в деке хотя бы один элемент. Если во входных данных встречается операция pop_front, pop_back, front, back, и при этом дек пуст, то программа должна вместо числового значения вывести строку error.

 

Входные данные
Каждая строка содержит одну команду.

Выходные данные
Для каждой команды вывести в отдельной строке соответствующий результат.

Тесты

Входные данные Выходные данные
1 front
back
pop_back
pop_front
exit
error
error
error
error
bye
2 push_back 1
back
exit
ok
1
bye
3 push_back 1
push_front 2
back
front
size
clear
size
pop_back
exit
ok
ok
1
2
2
ok
0
error
bye

Код программы

Описание

Структура данных «дек» реализована в виде двусвязного списка. В классе  MyDeque реализованы все требуемые методы. Те из них, после вызова которых, по условию, программа должна вывести некоторую строку, возвращают эту строку («ok» или «bye»). При попытке удалить или просмотреть элемент пустого дека создаётся и передаётся новый объект класса  DequeException, наследующего класс  Exception. В ходе работы функции main создаётся объект класса MyDeque, после чего читаются строки из входного потока и выполняются требуемые команды. В случае, если перехватывается исключение, выводится строка «error».

Код на ideone.com.

Засчитанное решение на e-olymp.com.

AL6

Условие

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

Входные данные

$latex ({([])})$

Выходные данные

Yes.

Код

Решение

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

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

e-olymp 2820. Перемещение коня

Постановка задачи

Ссылка на задачу с сайта e-olymp

Ваш друг проводит научные исследования по проблеме Конского Минимального Путешествия (КМП), которая состоит в том, чтобы найти кратчайший замкнутый тур ходов конём, который посещает каждую клетку заданного набора из [latex]n[/latex] клеток на шахматной доске ровно один раз. Он считает, что самая трудная часть задачи состоит в определении наименьшего числа ходов для перемещения коня между двумя заданными клетками и что, как только вы поможете ему решить эту подзадачу, то ему решить всю задачу будет намного легче.

Вы, конечно, знаете, что дело обстоит как раз наоборот. Таким образом, вы в свою очередь решили предложить ему самому написать программу, которая решает «трудную» часть.

Ваша задача состоит в том, чтобы написать программу, которая принимает координаты двух клеток [latex]n[/latex] и [latex]b[/latex] в качестве входных данных, а затем определяет количество ходов конем кратчайшим путём из [latex]a[/latex] в [latex]b[/latex].

Входные данные:

Входные данные будут содержать один или более тестов. Каждый тест состоит из одной строки, содержащей координаты двух клеток, разделенные одним пробелом. Координаты клетки являются двумя символами, первый из которых буква ([latex]a[/latex]—[latex]h[/latex]), задающая столбец и второй – цифра ([latex]1[/latex]—[latex]8[/latex]), задающая строку на шахматной доске.

Выходные данные:

Для каждого теста вывести одну строку следующего содержания: «Путь от xx к yy занимает n шагов»

Тест

Пример входных данных Пример выходных данных
[latex]e2[/latex] [latex]e4[/latex] Путь от [latex]e2[/latex] к [latex]e4[/latex] занимает [latex]2[/latex] шагов.
[latex]a1[/latex] [latex]b2[/latex] Путь от [latex]a1[/latex] к [latex]b2[/latex] занимает [latex]4[/latex] шагов.
[latex]b2[/latex] [latex]c3[/latex] Путь от [latex]b2[/latex] к [latex]c3[/latex] занимает [latex]2[/latex] шагов.
[latex]a1[/latex] [latex]h8[/latex] Путь от [latex]a1[/latex] к [latex]h8[/latex] занимает [latex]6[/latex] шагов.
[latex]a1[/latex] [latex]h7[/latex] Путь от [latex]a1[/latex] к [latex]h7[/latex] занимает [latex]5[/latex] шагов.
[latex]h8[/latex] [latex]a1[/latex] Путь от [latex]h8[/latex] к [latex]a1[/latex] занимает [latex]6[/latex] шагов.
[latex]b1[/latex] [latex]c3[/latex] Путь от [latex]b1[/latex] к [latex]c3[/latex] занимает [latex]1[/latex] шагов.
[latex]f6[/latex] f[latex]6[/latex] Путь от [latex]f6[/latex] к [latex]f6[/latex] занимает [latex]0[/latex] шагов.

 

Решение

Ссылка на решение задания с сайта e-olymp

Ссылка на решение задания на онлайн компиляторе Ideone.com

Описание решения

Для начала объявим переменные aи b типа char, где a и b — это координаты двух клеток. В цикле при помощи форматированного ввода по шаблону вводим 4 переменных, в которых a, ny — координата одной клетки и b, ty — координата другой клетки. nx — цифровая координата, которую мы получаем из буквы, отнимая от a.  Создаем очередь, добавляем начальную клетку и ищем все возможные ходы пока не попадем в нужную клетку. Чтобы получить длину пути, нужно хранить длины путей до данной клетки в матрице и обновлять ее, по ходу продвижения. Длина в начальной клетке — 0, а длина в каждой последующей — 1. На экран выводим количество шагов, которые необходимо сделать конем, чтобы попасть из одной клетки в другую.

e-olymp 6128. Простой дек

Постановка задачи

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

push_front

Добавить (положить) в начало дека новый элемент. Программа должна вывести ok.

push_back

Добавить (положить) в конец дека новый элемент. Программа должна вывести ok.

pop_front

Извлечь из дека первый элемент. Программа должна вывести его значение.

pop_back

Извлечь из дека последний элемент. Программа должна вывести его значение.

front

Узнать значение первого элемента (не удаляя его). Программа должна вывести его значение.

back

Узнать значение последнего элемента (не удаляя его). Программа должна вывести его значение.

size

Вывести количество элементов в деке.

clear

Очистить дек (удалить из него все элементы) и вывести ok.

exit

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

Гарантируется, что количество элементов в деке в любой момент не превосходит [latex]100[/latex]. Все операции:

  • pop_front,
  • pop_back,
  • front,
  • back

всегда корректны.

Объяснение: Количество элементов во всех структурах данных не превышает [latex]10000[/latex], если это не указано особо.

Также условие задачи можно посмотреть здесь.

Входные данные:

Описаны в условии. См. также пример входных данных.

Выходные данные:

Описаны в условии. См. также пример выходных данных.

Тесты

Входные данные Выходные данные
1 push_back 3
push_front 14
size
clear
push_front 1
back
push_back 2
front
pop_back
size
pop_front
size
exit
ok
ok
2
ok
ok
1
ok
1
2
1
1
0
bye
2 push_front 7
push_front 8
push_front 9
pop_back
back
push_front 11
size
pop_back
pop_back
pop_back
push_back 90
front
exit
ok
ok
ok
7
8
ok
3
8
9
11
ok
90
bye
3 push_back -5
push_back -20
push_back 2
pop_front
push_front 7
size
clear
pop_back
push_front 11
size
exit
ok
ok
ok
-5
ok
3
ok
-1
ok
1
bye

Посмотреть работу программы на примере первого теста можно на сайте ideone.

Решение

Описание решения

Чтобы смоделировать работу дека, напишем соответствующий класс class Deque, который будет содержать следующие поля:

  1. int[] data — массив для хранения данных внутри дека;
  2. static final int maxSize = 10000 — статическое неизменное поле, содержащее максимальное количество элементов в деке (по условию задачи 10000);
  3. int size — текущее количество элементов в деке;
  4. int head, end — индексы первого (верхнего) и последнего (нижнего) элементов дека в массиве int[] data.

Так как дек — это структура, в которой элементы можно добавлять и удалять как в начало, так и в конец, то индексы первого и последнего элементов в массиве будут постоянно изменяться при добавлении/удалении в дек объектов. Поэтому крайне важно организовать модель так, чтобы при произвольном добавлении в начало и конец дека новых элементов, массив содержал эти элементы в правильном порядке, а в программе не возникало ошибки выхода за границы массива.

Это сделано следующим образом: изначально индексы первого и последнего элементов массива data равны 0, как и размер массива (это описывается в конструкторе класса Deque). При добавлении в начало дека нового элемента, индекс первого элемента int head будет смещаться на 1 вперед, пока не достигнет верхней границы массива (9999), затем начнет свой отсчет опять с нуля. При добавлении нового элемента в конец дека, смещаться будет индекс последнего элемента, причем вниз, пока не достигнет 0, затем продолжит с верхней границы массива. Такой подход дает возможность непрерывно добавлять и удалять в дек элементы, однако если количество элементов в деке станет максимальным ( if (size == maxSize)), добавить новый элемент уже не получится, для него нужно освободить место.

При запуске программы, сперва создается объект класса Deque dq = new Deque(), затем программа принимает входные данные while((str = br.readLine()) != null) и вызывает соответствующий метод класса Deque.

Описание методов класса:

  1. push_front и push_back — добавление в дек нового элемента. Если текущее количество элементов в деке равен максимально допустимому количеству элементов, добавления происходить не будет, а программа выдаст предупреждающее сообщение. Если дек не пустой, количество элементов увеличится на 1, а сам элемент будет размещен в массиве с соответствующим индексом head или end (в зависимости от того, куда добавляется элемент, в верх или в низ). Этот индекс, соответственно, увеличится или уменьшится на 1. Если количество элементов в деке равно 0, вставка произойдет точно так же, однако индексы head и end останутся прежними, указывая таким образом на один и тот же элемент. После успешной вставки на экран будет выведено сообщение «ok».
  2. pop_front и pop_back — если в деке есть хотя бы 1 элемент, функция возвратит из массива data элемент с индексом head или end (соответственно для каждого метода), при этом этот индекс «двигается» в обратную для себя сторону (индекс верхнего элемента уменьшается, индекс нижнего — увеличивается), а количество элементов в деке уменьшается на 1. Если же дек пуст, функция вернет значение -1.
  3. back и front — методы, аналогичные pop_front и pop_back, с тем отличием, что не будут изменять индексы head и end или количество элементов в деке, а просто возвратят нужные элементы.
  4. size — возвращает количество элементов в деке ( return size;).
  5. clear — приравнивает поля size, head и end к 0, имитируя удаление из дека всех элементов. Выводит на экран сообщение «ok».
  6. exit — выводит на экран сообщение «bye», после чего программа завершит работу.

Посмотреть решение задания можно на сайте e-olymp.