AA26.

Задача

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

Тесты

Input Output
aabbcc ccbbaa
input data atput dani
 Kalamabanga aglamabanaK

Алгоритм

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

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

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

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

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

Ссылка на ideone.com

Related Images:

А701б

Условие

Даны квадратная матрица [latex]A[/latex] порядка [latex]n[/latex] и  вектор [latex]b[/latex] c [latex]n[/latex] элементами. Получить вектор [latex]{ A }^{ 2 }b[/latex]

Тесты

n A b Результат
 3 1 1 11 1 1

1 1 1

5 5 5 45  45 45
5 1 0 0 0 00 2 0 0 0

0 0 3 0 0

0 0 0 4 0

0 0 0 0 5

 8  1 8 1 8 8  4  72  16 200
2 1 00 1  2 2  2 2

Алгоритм

Считываем матрицу. Возводим ее в квадрат ( перемножение матрицы осуществляется при помощи циклов). Считываем вектор. Умножаем матрицу на вектор. Выводим ответ.

Фактически, умножение матриц пишется по определению. Сумма произведений элементов строки на элементы столбцов.

Ссылка на ideone.com

Related Images:

e-olymp 2479. Баланс скобок

Условие

(Ссылка на задачу в e-olymp)

Имеется строка, содержащая скобки () и []. Скобочное выражение считается правильным, если:

  • оно является пустым
  • если A и B правильны, то AB правильно
  • если A правильно, то (A) и [A] правильны

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

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

Первая строка содержит количество тестов n. Каждая из следующих n строк содержит выражение, состоящее из скобок () и [].

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

Для каждого теста вывести в отдельной строке «Yes«, если выражение является правильным и «No» иначе.

Тесты

3
([])
(([()])))
([()[]()])()
Yes
No
Yes

(тесты взяты с e-olymp.com)

Изображение для задачи 2479

Результаты задачи № 2479

Алгоритм

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

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

Ссылка на ideone.com

Related Images:

e-olymp 5072. Подсчет количества ребер (ОГ)

Задача

Ориентированный граф задан матрицей смежности.
Найдите количество ребер в графе.

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

Входной файл содержит число n (1n100) — число вершин в графе, и затем n строк по n чисел, каждое из которых равно или 1 — его матрицу смежности.

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

Выведите в выходной файл количество ребер заданного графа.

Решение

Задача на E-Olimp.

30  1 11 0 1

0 1 1

6
50 1 1 1 11 0 0 0 0

1 0 0 0 0

0 0 1 0 1

1 0 0 0 0

9
21 11 1 4

Алгоритм решения прост. Количество ребер ориентированного графа равно  количеству единиц в его матрице смежности. Поэтому просто считываем, суммируем если 1, и выводим ответ.

Задача на ideone

Related Images:

e-olymp 432. Подземелье

Подземелье

   Вы попали в 3D подземный лабиринт и необходимо найти быстрый выход! Карта подземелья составлена из единичных кубических комнат, по которым можно или нельзя передвигаться. Нужно всего одну минуту, чтобы переместиться она одну единицу на север, юг, восток, запад, вверх или вниз. Вы не можете двигаться по диагонали, и лабиринт окружен твердой скальной породой со всех сторон.

   Можно ли выбраться из лабиринта? Если да, то какое времени это займет?

Техническое условие

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

Состоит из ряда подземелий. Каждое описание подземелья начинается со строки, содержащей три целых числа: количество уровней в подземелье l, а также r и cколичество строк и столбцов, описывающих план каждого уровня (все числа не больше 30).

   Далее следует l блоков по r строк, каждая по c символов. Каждое число описывает одну ячейку подземелья. Запрещенные для перемещения кубы подземелья обозначены символом ‘#‘, а пустые клетки обозначены ‘.‘. Ваша стартовая позиция обозначается буквой ‘S‘, а выход буквой ‘Е‘. Все описания подземелий отделены пустой строкой. Описание входных данных заканчивается тремя нулями.

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

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

Escaped in X minute(s).

    где X — наименьшее время, необходимое для достижения выхода.

   Если достичь выход невозможно, вывести строку

   Trapped!


 

ТЕСТЫ:

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

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

 

Тесты взяты с сайта e-olimp. Подтверждение прохождения задачи на e-olimp.

Задача (Подземелья)

 

Задача на E-Olimp!

ССЫЛКА НА IDEONE.COM

(Программа также проверенна в Code::Blocks)


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

Основа всего алгоритма — поиск в ширину, реализованный на трехмерном массиве.  Для реализации я использовал собственную структуру очереди. В двух словах идея такова:
1) Считываем данные, заполняя массив по принципу:  Если «комната закрыта» — ставим -1. Если открыта — ставим ноль. Старт и Финиш также заполняем нулями, но запоминаем их координаты.
Также создаем массив булевых переменных, помогающий нам определять, посещали ли мы уже эту вершину. Этот массив вначале заполняется нулями.
2) Реализация самого поиска. Создаем очередь и помещаем в нее стартовую вершину.  Затем запускаем цикл до тех пор, пока очередь не пуста.
3) Действия в цикле повторяются шесть раз, на каждое из возможных направлений.
  • Проверяем закрыта ли эта комната ( проверка на положительное число)
  • Если комната открыта, проверяем, есть ли в ней уже какое то время. Если да, то кладем в нее минимум из времени пути который был уже проложен, и проложен сейчас. В противном случае, кладем в нее время данного пути.
  • Проверяем, была ли посещена эта комната ранее. В противном случае — отмечаем что она посещалась и добавляем ее в очередь.

4) Извлекаем вершину из очереди.

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

Примечание! 

1)Для удобной реализации поиска, оба массива создаем на два уровня больше, как бы делая ему рамку ( маску).

2) Поскольку в одном тесте идет не один набор уровней, программа выполняется в цикле, который работает до тех пор, пока не получит в качестве трех чисел — три нуля. ( В комментариях назовем этот цикл «внешним»)


 

 

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:

А400

Задача: Дана действительная квадратная матрица порядка [latex]n[/latex]. Получить [latex]{ x }_{ 1 }{ x }_{ n }+{ x }_{ 2 }{ x }_{ n-1 }+ \dots +{x }_{ n }{ x }_{ 1 }[/latex] , где [latex]{x }_{ k }[/latex]  — наибольшее значение элементов [latex]k[/latex]-й строки данной матрицы.

n Числа Результат n Числа Результат
4 1 1 1 15 5 5 56 6 6 6

2 2 2 3

66 3  1.25 99 45 4.2 5.20.3 0 0.2 86.44
5  1 2 3 4 19 8 4 3 10 50 9 2 1

1 2 1 1 1

3 1 2 0 5

2576 5  0 0 0 0 05 9 10008 72 1777799 98 100 10 100

0 0 0 0 0

9.842 8 7 66 54

1000

Код программы на С++

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

 

Суть задачи: находим максимум каждой строки  определяем их в отдельный массив. Затем перемножаем симметричные относительно середины массива элементы и суммируем их.

P.S. Простите, таблицу я так и не смог нормально отрегулировать….

Ссылка C++

Ссылка Java

Related Images:

А136ж

Задача: Даны натуральное число [latex]n[/latex], действительные числа  [latex]{ a }_{ 1 },\dots ,{ a }_{ n }[/latex]

Вычислить:  [latex]{ a }_{ 1 }-{ a }_{ 2 }+{ a }_{ 3 }-\dots +{ (-1) }^{ n+1 }{ a }_{n }[/latex]

(В этой задаче не требуется хранение исходных последовательностей значений)

n  [latex]{ a }_{ 1 },\dots ,{ a }_{ n }[/latex] Sum
5 7 4 3 3 3 6
10  1 1 2 2 3 3 4 4 5 6 -1
15 66 456 3334 23 0.86 -587 4332 82223 0.0008 0 -0.75 44 52 7777 43 -82108.9
5  0.0005 0.0006 0.06 0.00008 0.00003 0.05985

Код программы на С++

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

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

Ссылка C++

Ссылка Java

 

Related Images:

Ю 3.31

 Задача: Численно убедится в справедливости равенства для заданного значения аргумента [latex]x[/latex] на заданное значение погрешности [latex]\varepsilon [/latex]. вывести число итераций.

[latex]cosx=1-\frac { { x }^{ 2 } }{ 2! } +\frac { { x }^{ 4 } }{ 4! } -\dots +{ (-1) }^{ n }\frac { { x }^{ 2n } }{ (2n)! }+\dots[/latex]
x  Delta  Value  Step’s
0    [latex]0[/latex] 0.0000001 1 1
3.14     [latex]\pi[/latex]  0.00001 -1 7
1.57    [latex]\frac { \pi }{ 2 }[/latex]  0.00001 0.000795865 5
1.05    [latex]\frac { \pi }{ 3 }[/latex]   0.00001 0.497571 4
2.09    [latex]\frac { 2\pi }{ 3 }[/latex]   0.00001 -0.496189 6

Код программы на С++

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

Ссылка на Java

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

 

Related Images:

Ю4.6

 Задача: Угол между векторами

Найти угол между векторами    [latex]A(n)[/latex] и  [latex]B(n)[/latex]   используя формулу:

[latex]cos\varphi =\cfrac { \left( A,B \right) }{ \left| A \right| \cdot \left| B \right| } =\cfrac { \sum _{ i=1 }^{ n }{ { a }_{ i }{ b }_{ i } } }{ \sqrt { \sum _{ i=1 }^{ n }{ { a }_{ i }^{ 2 } } } \sqrt { \sum _{ i=1 }^{ n }{ { b }_{ i }^{ 2 } } } }[/latex]
  N  A(n)  B(n)  Rad & Deg
  2   3 4   4 3  0.283794         16.2596
  2   7 1   5 5  0.643501         36.8686
3 3 4 0 4 4 2 0.367208         21.0388
10 7 7 7 7 7 7 7 7 7 7 7 7 7 7 7 7 7 7 7 7 0               0
2 0 2 3 0 1.5708       89.9969
2 -3 5 4 -1 2.35619      134.995

Код программы на С++

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

Чтобы выполнить задачу, требуется всего лишь следовать вычислениям формулы. Для того, что бы узнать значение не косинуса а самого угла, применяем математическую функцию [latex]acos[/latex].

Ссылка C++

Ссылка на Java

Related Images:

A114ж

Задача:

Вычислить [latex]\prod _{ i=2 }^{ 100 }{ \frac { i+1 }{ i+2 } } ;[/latex]

Код программы на С++

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

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

Результат  = 0.0294118. ( Это и есть 1/34).

(«Математический хак» о котором написал Игорь Евгеньевич, есть сокращение этих сомножителей, а именно:

[latex] \frac { 3 }{ 4 } \cdot \frac { 4 }{ 5 } \cdot \frac { 5 }{ 6 } \cdot \cdot \cdot \cdot \frac { 101 }{ 102 } =\frac { 3 }{ 102 } =\frac { 1 }{ 34 } =0.02941176; [/latex]

 

Related Images:

A59б

Задача:

Для задачи (А.59(б)

Даны действительные числа

Определить, принадлежит ли точка с координатами x, y  заштрихованной области.

X  Y  Ответ
-0.65 -0.75  Yes
-0.95 -0.59 No
700 8 No
0 0 No
0.56 0.75 Yes
1,0011 1,0012 No
0.6 0 Yes

Код программы на С++

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

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

Если точка лежит на самой окружности, мы считаем что она принадлежит нужной нам области.

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

 

Related Images:

Ю1.8

Задача:

Среднегодовая производительность труда

За первый год производительность труда на предприятии возросла на [latex]p[/latex]1[latex]%[/latex], за второй и третий — соответственно на [latex]p[/latex]2[latex]%[/latex] и  [latex]p[/latex]3[latex]%.[/latex] Найти среднегодовой прирост производительности (в процентах).

P1(%) P2(%) P3(%) Р (среднегодовой прирост  производительности)  (%)
50 68 34 50.03
0 25 75 29.81
-25 25 78 18.61
0 -25 0 -9.14
1.4 43 0.7 13.45

Код программы на С++

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

Алгоритм задачи предельно прост.

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

Предположим, что производительность труда в году, предшествующему увеличению, это  [latex]a[/latex], тогда в следующем году прирост будет вычисляться по формуле  [latex]a\cdot \left( \frac { { p }_{ n } }{ 100 } +1 \right)[/latex], где  [latex]{ p }_{ n }[/latex] это показатель прироста производительности за соответствующий год.

Учитывая, что для каждого следующего года показатель [latex]a[/latex] это производительность за предыдущий год, мы получим формулу:

[latex]p=\left( \sqrt [ 3 ]{ (\frac { { p }_{ 1 } }{ 100 } +1)\cdot (\frac { { p }_{ 2 } }{ 100 } +1)\cdot (\frac { { p }_{ 3 } }{ 100 } +1) } -1 \right) \cdot 100[/latex].

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

Related Images:

Ю2.8

Задача

Пройдет ли кирпич со сторонами [latex]a[/latex], [latex]b[/latex] и [latex]c[/latex] сквозь прямоугольное отверстие со сторонами [latex]r[/latex] и [latex]s[/latex]? Стороны отверстия должны быть параллельны граням кирпича.

A B C R S Ответ
10 8 7 4 3 Impossible
1 9 8 5 9 Possible
5 5 5 8 2 Impossible
4.5 4 4 5 5 Possible
0.5 3.4 0.8 4 2.5 Possible

Код программы на C++

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

 

В этой задаче я считаю, что если длины соответствующих сторон равны — то кирпич проходит не будет. Также считаем что ни одна из сторон не может быть нулем. Поскольку нам надо проверить входит ли кирпич в щель в общем, мы имеем право рассматривать три варианта положения кирпича относительно щели. Во всех трех случаях алгоритм одинаков. Он состоит в сравнении сторон щели и сторон грани.  По крайней мере две стороны кирпича должны быть меньше двух сторон щели. Если два условия выполняются — то переменной [latex]x[/latex] присваивают значение true и выводится на экран сообщение, что выполнить задачу возможно. В противном случае значение переменной останется неизменным. Как следствие будет выведено на экран сообщение, что эта задача не разрешима.

Related Images: