e-olymp 1776. Рельсы

Ссылка на условие задачи: http://www.e-olymp.com/ru/problems/1776.

Ссылка на засчитанное решение.

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

Иллюстрация

Местная традиция гласит, что каждый поезд приходящий со стороны A продолжает свое движение в направлении B, при этом его вагоны перестанавливаются в некотором порядке. Предположим, что каждый поезд, приходящий из направления A, имеет n1000 вагонов, пронумерованных в возрастающем порядке 1, 2, …, n. Ответственный за реорганизацию вагонов должен знать, возможно ли перевезти их в направлении B в порядке a1, a2, …, an. Помогите ему написать программу, которая определит возможна ли такая перестановка вагонов. Вагоны можно отсоединять от поезда до того как они попадут на станцию и можно их отдельно передвигать пока все они не буду находиться в направлении B. На станции в любой момент времени может находиться любое количество вагонов. Но если вагон зашел на станцию, он уже не может вернуться на колею в направлении A, а также если он уже выехал в направлении B, то уже не может вернуться на станцию.

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

Состоит из нескольких тестов. Каждый тест кроме последнего описывает один поезд и возможно несколько требований для его реорганизации. Первая строка теста содержит целое число n. Каждая из следующих строк теста содержит перестановку 1, 2, …, n. Последняя строка блока содержит 0.
Последний тест состоит из единственной строки, содержащей 0.

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

Для каждой входной строки, содержащей перестановку чисел, следует вывести Yes, если можно совершить указанную перестановку вагонов, и No иначе. После вывода ответов на все перестановки каждого теста следует вывести пустую строку. Для последнего нулевого теста ничего выводить не следует.

Решение

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

Код программы: http://ideone.com/2p9seU.

Related Images:

AA26.

Задача

В строке заменить последний и предпоследний символ, соответственно, на первый и второй. Если длина строки меньше четырех, то вывести, что это сделать невозможно.

Тесты

Input Output
aabbcc ccbbaa
input data atput dani
 Kalamabanga aglamabanaK

Алгоритм

Поскольку в условии задачи, количество слов не оговорено — для  ввода строки используем функцию getline. Затем проверяем ее длину. Если количество символов ( пробел также учитывается как символ!) не меньше 4, то делаем следующее:

1) Кладем в дополнительную строку два последних символа.

2) Заменяем последние символы в исходной строке на первые

3) В первые символы кладем то, что сохранили в дополнительной строке.

Если число символов меньше 4 — выдаем сообщение об ошибке.

Ссылка на ideone.com

Related Images:

А1043

Задача

Построить все правильные скобочные выражения длины 10, то есть, которые содержат по 5 левых и по 5 правых скобок.

Код на языке С++:

Посмотреть программу можно здесь

Код на языке Java:

Ссылка на программу: http://ideone.com/9MjHSA

Решение:

В переменной [latex]x[/latex] мы будем хранить количество открытых ([latex]»(«[/latex]) скобок. Далее  проверяем условие, что если [latex]x>0[/latex], то можем поставить закрывающую ([latex]»)»[/latex]) скобку. Идем дальше, смотрим сколько свободных мест осталось и если мест осталось столько же, сколько открывающих, то все остальные закрывающие.

Related Images:

AA14

Задача. В заданной строке удалить первый символ «.», который найдется в строке.

17.05.2015 1705.2015
.РЛ. РЛ.
Удачи, мистер Горски Нет точек
Вводим строку. Ищем первое вхождение символа «.», после чего выходим из цикла и удаляем этот символ. И добавляем условие, когда точек нет.

Код программы можно посмотреть тут 

Related Images:

AA8

Задача

Заданы две одинаковые по длине строки. Построить новую строку, в которой на четных местах расположены элементы первой строки, а на нечетных – элементы второй строки.

Тесты

Ввод Вывод
abc

012

a0b1c2
0123

0123

00112233

 

Related Images:

AA1

Задача:

В заданной строке заменить подряд идущие пробелы на один пробел.

Примечание:

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

Тестирование:

 Исходная строка  Оптимистичное ожидание Комментарий
Gagarin               became an                     international celebrity, and was                                              awarded many                     medals and titles, including                       Hero of the                        Soviet Union. Gagarin became an international celebrity, and was awarded many medals and titles, including Hero of the Soviet Union.  Пройден.
 Leonardo                             was, and                             is,                                         renowned                               primarily                         as a                             painter. Leonardo was, and is, renowned primarily as a painter.  Пройден.

Код на С++

Код на Java

 

Пояснение:

Вариант удаления пробелов с помощью [latex]erase()[/latex] является самым очевидным. Но у него больше недостатков, чем достоинств. Данный метод имеет линейную асимптотику, в худшем случае он выполнил бы [latex]n — 1[/latex] ( в дальнейшем [latex]»n»[/latex] — это длина строки ) сдвиг в индексах строки.

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

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

 

Related Images:

AA27

Задача: В строке вставить после предпоследнего символа первый и второй символ строки. Если длина строки меньше четырех, то вывести, что это сделать невозможно.

[latex]s1[/latex] [latex]s2[/latex] Комментарий
qwerty qwertqwy Тест пройден
_ qwert y _ qwert _ y Тест пройден
qwe Невозможно выполнить операцию.

C++:

Java:

Дана строка [latex]s1[/latex]. Переписываем из неё в строку [latex]s2[/latex] все символы, кроме последнего. Добавляем первый, второй и последний символ строки [latex]s1[/latex] в строку [latex]s2[/latex].

Задача на Ideone:
C++
Java

Related Images:

e-olimp 553. Рекурсия

Задача: Рекурсия

Решение

ссылка на ideone, засчитанное решение на e-olimp

Идея решения

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

Было решено использовать map<string,set<string>> как структуру для описания графа: каждая вершина — это строка и у каждой вершины есть множество вершин (строк), смежных с ней.
А еще задача имеет классификацию — поиск в глубину, что как бы намекает.

Related Images:

АА24

Задача

 Ввести строку S и целое положительное число N, а также символы C1 и С2. Заменить каждое вхождение символа C1 на N символов C2.

Тесты

Данная строка C1 C2 n Получаемая строка Комментарий
a111a111 a = 3 ===111===111 пройден
omnomnom n  1 om-om-om пройден
Nina N Z 1 Zina пройден

Решение

 Мы идем по данной строке, если попадаем на символ, который не нужно заменять (не С1), то просто переписываем его в новую строку, если попадаем на символ С1, записываем в созданную новую строку n символов С2.

Код на Java:
 

Related Images:

AA1

Задача.  В заданной строке заменить подряд идущие пробелы на один пробел.

Тесты:

Ввод Вывод Комментарий
as  fg   t as fg t Пройден
   rty g  uio  rty g uio Пройден
Решение:

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

С работой программы можно ознакомиться здесь.

Related Images:

AA21

Задача. В строке сосчитать количество всех открывающих (квадратных, круглых и фигурных) и закрывающих скобок. Если открывающих скобок на одну больше, добавить закрывающую круглую скобку в конец, а если открывающих скобок на одну меньше, то удалить последнюю закрывающую.

Тесты:

Ввод Результат Комментарий
./main «({){«  «({){« Пройдено
./main «({}){«  «({}){)» Пройдено
./main «)]}]([[«  «)]}([[« Пройдено

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

Идея решения:
Сосчитать кол-во открывающих и закрывающих скобок в одну переменную. Если текущий символ — открывающая скобка, то прибавить к переменной единицу, если закрывающая скобка, то отнять единицу. Совершать проверку переменной на равенство 1 (если на одну открывающую скобку больше) или -1 (если на одну открывающую скобку меньше).

Скриншот:
AA21

Related Images:

AA3

Задача

В заданной строке заменить каждую цифру символом «*».

Тест

Ввод Вывод
a;iejfhu789LKSKJD55ahg7 a;iejfhu***LKSKJD**ahg*
123456789 *********
Q1D2F3G4H5J6K7L8’\ Q*D*F*G*H*J*K*L*’\
Guten Abend!Ich heise Katja. Ich bin 18 Jahre alt Guten Abend!Ich heise Katja. Ich bin  **  Jahre alt
Cсылка на программу:http://ideone.com/CoqOFb

Решение:

Пробежимся по всей строке и проверим каждый символ. Если найдется цифра, то меняем ее на «*», и выводим исправленный текст.

 

Related Images:

AA6

Задача

В заданной строке  дописать после каждого символа «!» символ «?».

Решение. 

Проверяем каждый символ строки до тех пор пока не встретится «!», после чего добавляем после него «?».

 

Input Output
Hello, world! Hello, world!?
 Why are we here?? Why are we here??
 !!!It’s ! a ! problem ! ! !?!?!?It’s !? a !? problem !? !?

Код на Java

 

Related Images:

AA19

Постановка задачи: В заданной строке заменить три точки, идущие подряд, тремя первыми символами строки.

Алгоритм решения: Если строка не начинается с троеточия, последовательно заменять все его вхождения.

Тесты

Input Output
the more I code … better my coding becomes the more I code the better my coding becomes
…what am I supposed to do? …what am I supposed to do?
abc……… abcabcabc

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


1. C, c-string,


2. C++, string


Related Images:

A808г

Задача

Дан текст. Группы символов, разделенные пробелами (одним или несколькими) и не содержащие пробелы внутри себя, будем называть их словами.В тех словах, которые оканчиваются сочитанием букв  [latex]-ing[/latex] заменить это окончание на [latex]-ed[/latex].

Тест

Для проверки я введу первый абзац и второй, так как могут возникнуть вопросы, связанные с считыванием [latex]getline()[/latex] до первого переноса строки.

Вводимый текст Выводимый текст
Alice was beginning to get very tired of sitting

by her sister on the bank, and of having nothing

to do: once or twice she had peened into the book

her sister was reading, but it had no pictures or con-

versations in it, and what is the use of a book,’ througt

Alice ‘without pictures or conversation?’

So she was considering in her own ..

Alice was begined to get very tired of sitted

by her sister on the bank, and of haved nothed

to do: once or twice she had peened into the book

her sister was readed

, but it had no pictures or con-

versations in it, and what is the use of a book,’ througt

Alice ‘without pictures or conversation?’

So she was considered in her own …

Ссылка на программу: http://ideone.com/S5ZlwZ

Решение

Вводим строку в переменную [latex]s[/latex].В цикле пишем условие, что пока будут встречаться буквосочетания  [latex]-ing[/latex] заменить их на [latex]-ed[/latex] и выводим уже обработанный текст.

Related Images:

А816

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

Тесты*:

 Инфиксная форма Постфиксная форма Инфиксная форма Постфиксная форма
3+4 3 4 +   3+4*2/(1-5)^2  3 4 2 * 1 5 — 2 ^ / +
(5-4)+2 5 4 — 2 +  (1+2)*4+3  1 2 + 4 * 3 +
2*(3+4)*5 2 3 4 + * 5 *  78^6-3+9^(2-1)  78 6 ^ 3 — 9 2 1 — ^ +

*тесты взяты из примеров Абрамова, примеры из Википедии и немного собственных тестов.

Несколько оговорок по поводу программы:

1. Я расширил множество допустимых операторов добавив туда возведение в  степень

2. Программа предполагает, что в выражении согласованы все скобки, иначе она будет работать не правильно.

3. В реализации программы через массив символов я предположил что  вводимое выражение не будет превышать 50 символов. ( то есть, если учитывать пробелы, то финальная строка не будет превышать 100 символов)

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

Вообще постфиксная запись еще называется Обратной Польской Нотацией ( ОПН). За алгоритмом преобразования выражений из инфиксной ( привычной нам формы записи) в ОНП можно обратится к Википедии.

Алгоритм

  • Пока есть ещё символы для чтения:
  • Читаем очередной символ.
  • Если символ является числом, добавляем его к выходной строке..
  • Если символ является открывающей скобкой, помещаем его в стек.
  • Если символ является закрывающей скобкой:
До тех пор, пока верхним элементом стека не станет открывающая скобка, выталкиваем элементы из стека в выходную строку. При этом открывающая скобка удаляется из стека, но в выходную строку не добавляется. Если стек закончился раньше, чем мы встретили открывающую скобку, это означает, что в выражении либо неверно поставлен разделитель, либо не согласованы скобки.
  • Если символ является оператором о1, тогда:
1) пока приоритет o1 меньше либо равен приоритету оператора, находящегося на вершине стека выталкиваем верхние элементы стека в выходную строку;
2) помещаем оператор o1 в стек.
  • Когда входная строка закончилась, выталкиваем все символы из стека в выходную строку. В стеке должны были остаться только символы операторов; если это не так, значит в выражении не согласованы скобки.

 

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

Реализация через <string>

ССЫЛКА

Моменты которые следовало бы объяснить:

1) Зачем мы проверяем, является ли предыдущий символ числом, если данный тоже число?

Эта проверка помогает нам определить, сколько цифр имело наше число. Без данной проверки, например, выражение: [latex]34*2-1[/latex]  будет иметь вид не  [latex]34 2 * 1 — [/latex] , а  [latex]3 4 2 * 1 — [/latex]. В этом случае возникает двоякость при чтении выражения. Преобразовывая обратно можно предположить, что исходное выражение было  [latex]3*42-1[/latex].

2) Зачем мы делаем замену символам умножения и вычитания, в случае когда читаемый символ это оператор?

Причина состоит в том, что нам требуется правильно контролировать приоритеты операций. Если распечатать  номера символов то мы увидим следующее:

А по своему приоритету, операции сортируются так:

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

В общем, детали реализации состоят  в том, что к строке stack  мы обращаемся через функции, как к стеку символов. В общем — программа просто реализует описанный выше алгоритм.

Реализация через массив char

ССЫЛКА

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

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

Related Images:

А808 б

Задача :

Дан текст. Группы символов, разделенные пробелами (одним или несколькими) и не содержащие пробелов внутри себя, будем называть, как и прежде, словами. Найти все слова, содержащие наибольшее количество гласных латинских букв ( a, e, i, o, u ).

Тесты :

Исходный текст Обработанный текст
Two households, both alike in dignity,
In fair Verona, where we lay our scene,
From ancient grudge break to new mutiny,
Where civil blood makes civil hands unclean.
households,
unclean.
alike
Verona,
ancient
makes
mutiny,
Where
break
grudge
civil
scene,
our
blood
where
fair
civil
dignity,
From
hands
new
to
Two
lay
we
in
both
In
For never was a story of more  woe . Than this of Juliet and her Romeo. Juliet  Romeo  never  more  woe for was a story of Than this of and her 

 

 

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

Ссылка на программу :  http://ideone.com/xXCrPe

Решение :

Для решение этой задачи я воспользовалась возможностью, которую предоставляет мне библиотека algorithm .

  1. Объявляем  переменные – флаги и счетчики для всех видов слов.
  2. Функция для завершения чтения слова и увеличение счетчика слова на единицу
  3. Стандартный строковый объект класса string.
  4. Ввод текста из стандартного потока ввода
  5. Проход по символам текста
  6. Считаем
  7. Сортируем

Related Images:

А812ж

Задача.

Дан текст, каждый символ которого может быть малой буквой, цифрой или одним из знаков +, -, *. Группой букв будем называть такую совокупность последовательно расположенных букв, которой непосредственно не предшествует и за которой непосредственно не следует буква. Аналогично определим группу цифр и группу знаков.

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

Тесты.

Ввод Вывод
1aa2bb+-c2cc—**22 22
11aa2bb+-c2cc—**22 11
1aa2bb+-c23cc—**22 23
111aa2bb+-c2cc—**22 111
1aa2bb+-c234cc—**22 234
1aa221bb+-c234cc—**22 221

Код программы (string):

Код программы (cstring):

Решение.

Вводим строку в переменную s. В первом цикле ищем наибольшую группу записывая значение в переменную n. В следующем цикле ищем номер первого символа в группе записывая значение в переменную a. В третьем цикле выводим символы с номерами с a-го по a+n.

Related Images:

Ю12.13

Задача

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

Тесты:

Текст Результат Комментарий
SOS  …—…  пройден
 A true SOS !!!  .- -…- — .-. ..- . -…- … — … -…- —..— —..— —..— -…-  пройден

 

Код:

Я создала ассоциативный  массив  через map, и связала буквы («ключ«) и соответствующие им значения в азбуке Морзе («значение«). Чтобы не заполнять его еще и большими буквами, во вводимом тексте уменьшаю буквы с помощью функции tolower .  

Решение через c-string :

Ссылки:

string

c-string.

Решение на Java:

 

Related Images:

Ю12.20

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

Ввод Вывод
qwerty
ytrewq
av
ab
va
tg
qwerty — ytrewq
av — va
12345
45
67
54
123567
543
54321
12345 — 54321
45 — 54

 

 

Записываем каждое слово словаря в вектор. А цикле переворачиваем каждое слово вектора и потом в цикле сравниваем его с каждым словом в словаре, если найдено обратное слово, то закидываем пару слов в новый вектор. Выводим вектор из пар слов на экран.

Ideone.

Related Images: