e-olymp 1266. CD

Вам предстоит длительное путешествие на автомобиле. К сожалению, у Вас в машине есть только магнитофон, а лучшая музыка записана на компакт дисках. У Вас есть чистая магнитофонная лента с длительностью звучания [latex]N[/latex] минут. Вам нужно выбрать песни для записи на магнитофонную ленту таким образом, чтобы не используемое на ней место было минимально.

Предположения:

  • количество треков на CD не превышает [latex]100[/latex]
  • ни один трек не длится более [latex]N[/latex] минут
  • длина каждого трека выражена целым числом
  • [latex]N[/latex] также целое [latex](0\leq[/latex][latex]N\leq[/latex][latex]200)[/latex]

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

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

Входные данные содержат несколько строк. В каждой строке сначала задано число [latex]N[/latex], далее количество треков и длительность звучания каждого трека. Все числа разделены пробелами. Например, в первой строке входных данных первым задано [latex]N=5[/latex], далее количество треков [latex]s=3[/latex], первый трек имеет длительность [latex]1[/latex] минуту, второй — [latex]3[/latex] минуты, и последний — [latex]4[/latex] минуты.

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

Выведите строку «sum:» и далее продолжительность записи.

Входные данные Выходные данные
5 3 1 3 4
10 4 9 8 4 2
20 4 10 5 7 4
90 8 10 23 1 2 3 4 5 7
45 8 4 10 44 43 12 9 8 2
sum:5
sum:10
sum:19
sum:55
sum:45

Код:

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

Ссылка на ideone

Ссылка на ideone

Алгоритм решения построен на методе динамического программирования.

Возможны два варианта:

  1. Либо трек не попал на диск, следовательно длинна уже записанных треков на диск [latex](d[j][i])[/latex] равна предыдущему числу ранее записанных треков [latex](d[j][i-1])[/latex].
  2. Либо трек попал на диск, а значит [latex]d[j][i][/latex] равно максимуму из суммы ранее записанных треков [latex](d[j][i-1])[/latex] и суммы заданной длинны [latex]arr[i][/latex] c [latex]d[j-arr[i]][i-1]][/latex], где [latex]d[j-arr[i]][i-1]][/latex] равен сумме уже записанных треков при предыдущем элементе массива [latex]arr[i-1][/latex]

А712

Задача

Дана квадратная матрица [latex]A[/latex] порядка [latex]n[/latex]. Получить матрицы [latex]\frac{1}{2}(A+A^{*}) (1)[/latex] и [latex]\frac{1}{2}(A-A^{*}) (2)[/latex].

Тесты:

Ввод Вывод (1) Вывод (2)
3
1 2 3
2 4 6
1 4 8
1 2 2
2 4 5
2 5 8
0 0 1
0 0 1
-1 -1 0

Код:

Ссылка на ideone.

Сначала, вводим размер матрицы и саму матрицу, сразу же транспонируем ее. Теперь каждый элемент обычной матрицы прибавляем к транспонированному и отнимаем от транспонированного в последствии умножая на [latex]\frac{1}{2}[/latex]. Записываем это в две различные матрицы с результатом и выводим их на экран.

Код на Java

 

e-olymp 5073. Проверка на наличие параллельных ребер (ОГ)

Ориентированный граф задан списком ребер.

Проверьте, содержит ли он параллельные ребра.

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

Входной файл содержит числа [latex]n(1\leq n\leq 100)[/latex] — число вершин в графе и [latex]m(1\leq m\leq 10000)[/latex]  — число ребер. Затем следует [latex]m[/latex] пар чисел — ребра графа.

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

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

Задача на e-olimp. Ссылка на засчитанное решение.

Входные данные Выходные данные
3 4
1 2
2 3
1 3
2 1
NO
3 4
1 2
2 3
1 3
2 3
YES

Код задачи:

Ссылка на ideone.

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

Сначала, добавим пару вершин в разные массивы так, чтоб нулевой элемент массива [latex]v[i][/latex] был началом ребра, а нулевой элемент массива [latex]g[i][/latex] — концом ребра и т.д. После этого в цикле будем сравнивать поочередно пары вершин до тех пор, пока не узнаем, что такая пара вершин уже встречалась, в таком случае выводим YES и завершаем цикл. В противном случае, если наше условие не выполнилось ни разу (т.е. переменная [latex]k[/latex] как была нулем в начале программы, так и осталась) выводим NO.

Код на Java

 

AA6

Задача

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

Решение. 

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

 

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

Код на Java

 

Ю 4.37

Задача

Автостоп-2. Из пункта А в пункт В, между которыми [latex]s[/latex] км, выехал велосипедист с постоянной скоростью [latex]v_{0}[/latex] км/ч. Навстречу ему — из пункта В — другой путешественник решил добраться «автостопом» — на разных видах попутного транспорта. Перед каждым участком он [latex]\tau _{i}[/latex] минут «голосует», ожидая попутного транспорта, затем движется [latex]t _{i}[/latex]  часов со скоростью [latex]v _{i}[/latex] км/час ( величины [latex]\tau _{i}, t _{i}, v _{i}, i=1,2,\ldots,n[/latex]  заданы в соответствующих массивах). Через какое время после старта и на каком расстоянии от пункта А путники встретятся?

Тесты

s [latex]v_{0}[/latex] n [latex]\tau _{i}[/latex] [latex]t _{i}[/latex] [latex]v _{i}[/latex] place, км  time, ч Комментарий
100.0 30.0  1 60.0 1.0 40.0 60.0 2.0 Пройден
100.0 10.0 1 0.0 1.0 40.0 Путники не доехали до места встречи Не пройден
130.0 15.0 2 0.0 3.0 1.0 2.6 40.0 33.3 2.587267 38.809006 Пройден

 

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

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

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

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

Код на Java

 

Ю11.13

Задача

Метод Рунге-Кутта. Найти приближенное решение обыкновенного дифференциального уравнения  [latex]y^\prime=f(x,y), y(a)=y_{0}[/latex] методом Рунге-Кутта пятого порядка на отрезке [latex][a,b][/latex] с заданным шагом [latex]h[/latex]. Значения функции [latex]y(x)[/latex] в узловых точках вычисляется по формуле: [latex]y_{i+1}=y_{i}+\frac{h}{6}(k_{1}+2k_{2}+2k_{3}+k_{4}), i=0,1,2,\cdots[/latex], где [latex]k_{1}=f(x_{i},y_{i}); k_{2}=f(x_{i}+\frac{h}{2},y_{i}+\frac{h}{2}k_{1});[/latex][latex]k_{3}=f(x_{i}+\frac{h}{2},y_{i}+\frac{h}{2}k_{2}); k_{4}=f(x_{i}+h,y_{i}+hk_{3})[/latex].

Решим дифференциальное уравнение такого вида: [latex]y^\prime=x+y[/latex] при начальном условии [latex]y(0)=1[/latex] на отрезке [latex][0, 0.5][/latex] с шагом интегрирования [latex]h=0.1[/latex]

Screenshot_1

Screenshot_2

 

Screenshot_3

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

Для решения примера введем данные во входной поток в таком порядке: [latex]0.0[/latex], [latex]0.5[/latex], [latex]0.1[/latex], [latex]1.0[/latex], где первое и второе число — начало и конец отрезка интегрирования соответственно, третье — шаг интегрирования и четвертое — значение [latex]y[/latex] в точке [latex]a[/latex] (в начале отрезка), т.е. [latex]y(a)=y(0)[/latex].

В программе присутствует функция, которой мы передаем параметры [latex]x, y[/latex] и которая возвращает само дифференциальное уравнение. Далее, в цикле высчитываем значения [latex]k_{1},k_{2},k_{3},k_{4}[/latex], передавая каждый раз параметры в функцию с шагом [latex]h[/latex] до тех пор пока не дойдем до конца промежутка. После завершения цикла выводим значение [latex]y_{0}[/latex].

 

А170

Задача. Даны натуральные числа [latex]n, a_{1}, a_{2},\ldots, a_{n} (n\geq 4)[/latex]. Числа [latex]a_{1}, a_{2},\ldots , a_{n}[/latex] — это измеренные в сотых долях секунды результаты [latex]n[/latex] спортсменов в беге на [latex]100[/latex] м. Составить команду из четырёх лучших бегунов для участия в эстафете [latex]4\times100[/latex], т.е. указать одну из четверок натуральных чисел [latex]i, j, k, l[/latex], для которой [latex]1\leq i\leq j\leq k\leq l\leq n[/latex] и [latex]a_{i} + a_{j}+a_{k} + a_{l}[/latex] имеет наименьшее значение.

Тесты

      n         c Результаты бега спортсменов Номера спортсменов, избранных для команды Комментарий
6 3 11.77 12.34 12.14 11.15 11.16 11.40 4 5 6 Пройден
6 4 11.68 0 12.15 11.54 11.26 11.00 Введен отрицательный или нулевой результат Не пройден
6 2 11.68 -12.34 12.14 11.55 11.29 11.00 Введен отрицательный или нулевой результат Не пройден

 

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

В этой задаче необходимо было найти номера лучших бегунов, для создания из них команды. Размер команды вводим сразу же после общего количества бегунов с клавиатуры. Для нахождения номеров бегунов нам потребуется функция mini, которая находит минимальный элемент массива и возвращает его значение, а также  функция team, вызывающая функцию mini. В функции team уже создан массив номеров бегунов, в который мы вначале  введем данные и отсортируем его по возрастанию. Также будем выводить номер этого минимального элемента на экран, прибавляя 1 (как бы считая бегунов с 1, а не с 0),  и присваивать этому (найденному) элементу массива какое-то большое значение для того, чтобы при следующей проверке программа не считала его минимальным элементом, а находила следующий минимальный.

В строках

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

В конечном итоге, применяем функцию team и получаем, собственно, ответ.

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

 

Ю3.36

Задача

Численно убедиться в справедливости равенства, для чего для заданного значения аргумента [latex]x[/latex] вычислить левую его часть и разложение, стоящее в правой части, с заданной погрешностью [latex]\varepsilon[/latex]. Испытать разложение на сходимость при разных значениях аргумента, оценить скорость сходимости, для чего вывести число итераций [latex]n[/latex] (слагаемых или сомножителей), необходимых для достижения заданной точности.

[latex]\frac { { e }^{ x }+{ e }^{ -x } }{ 2 } =1+\frac { { x }^{ 2 } }{ 2! } +\frac { { x }^{ 4 } }{ 4! } +\cdots+\frac { { x }^{ 2n } }{ (2n)! } +\cdots[/latex]

Тесты

   x [latex]\varepsilon[/latex] Левая часть Правая часть    n Разность Комментарий
3 0.00005 10.0676619958  10.0676598764 8 0.0000021194 Пройден
 11.33  0.0000314 41641.5114284855 41641.5114045419 19 0.0000239436 Пройден
 6 0 Погрешность равна 0, тогда правая часть стремится к левой 201.7156361225 (n=бесконечность)​  Не пройден

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

В данной задаче необходимо было доказать равенство при заданном [latex]x[/latex] и [latex]\varepsilon [/latex].

Для этого вначале высчитывалось значение левой части [latex]\frac { { e }^{ x }+{ e }^{ -x } }{ 2 } [/latex] при заданном [latex]x[/latex], а далее, в цикле, высчитывалось значение правой части [latex]\frac { { x }^{ 2 } }{ 2! } +\frac { { x }^{ 4 } }{ 4! } +…+\frac { { x }^{ 2n } }{ (2n)! } +…[/latex]. В цикле программа находила последующий элемент последовательности, стоящей в правой части равенства, каждый раз умножая предыдущий элемент на [latex]\frac { { x }^{ 2 } }{ (2n-1)*(2n) } [/latex] до тех пор пока разность между левой и правой частью равенства [latex]dife=left-right[/latex]  не стала меньше заданной погрешности, заданной по модулю [latex]dife < \left|\varepsilon \right|[/latex]. После завершения цикла программа запоминает последнее значение [latex]n[/latex] и после этого выводит его на экран.

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

 

Ragnarök — Power of Thor

Четвертая по счету игра на сайте называется Ragnarök — Power of Thor, где нам посчастливилось быть Великим Воином Тором. Тору необходимо самым кратчайшим путем добраться до источника энергии, которая придаст ему еще больше сил и уверенности в дальнейших сражениях.

Пока еще не всемогущий Тор ждет указаний

Пока еще не всемогущий Тор ждет указаний

Инициализация

В начале нам сообщают положение на карте источника и самого персонажа (их координаты по X и Y) (int LX, LY) (int TX, TY) соответственно.

Игровой цикл

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

Вход

В самом игровом цикле нам сообщают величину энергии Тора (int E), которая уменьшается на 1 с каждым последующим ходом.

Выход

В выходной поток необходимо вывести одну строку. Нам представлено всего 8 возможных вариантов дальнейшего передвижения Тора. Screenshot_2222

 

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

Перевод строки на новую обязателен.

 

Тест 1

Запуская программу впервые, Тор будет сам не свой, двигаясь совсем не по направлению к источнику.

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

[su_spoiler title=»Адекватное решение» icon=»arrow-circle-2″]

Немного подумав вспоминаем, что нам даны начальные координаты как источника так и энергии. Сразу же приходит в голову мысль, что их надо сравнивать.

Если равны координаты Тора и источника энергии по X, то тут мы находим разность координат источника и Тора по Y, если LY — TY > 0 (Источник находится выше Тора по оси Y), то идем на юг (вверх), в противном случае на север (вниз). Аналогично и с движением по Y,  что дает нам силы пройти первые два теста.

[/su_spoiler]

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

[su_spoiler title=»Цикл for идет на помощь» icon=»arrow-circle-2″]

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

Код на C++:

Код на Java:

 

Получается вот такой вот симпатичный код, описывающий все возможные ситуации по передвижению Тора (переносит Тора к источнику из любой точки карты). Разбивая на два возможных случая, движение в правой половине карты и в левой половине карты, получается, что программа охватывает любую ее точку. В самом цикле возьмем модуль между разностью (т.к. источник может находиться и ниже Тора). Сравниваем LX и TX, для того, чтобы узнать в какой половине карты находится источник. Если LX — TX > 0, то в цикле будем отнимать от LX, в противном случае — от TX, дабы не получить отрицательные значения. В конечном счете переменная E (энергия) там так и не понадобилось, так как воин и так находил кратчайшее расстояние.

[/su_spoiler]

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

Skynet — The Chasm

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

Ни о чем не подозревающий мотоциклист

Ни о чем не подозревающий мотоциклист

Инициализация

В начале нам сообщают всевозможные данные о будущем пути: расстояние от мотоциклиста до пропасти (int R), длину пропасти (int G), длину платформы для приземления (int L).

Игровой цикл

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

Вход

Каждый новый ход (т.е. после каждого следующего выполненного действия в самом цикле while) нам сообщают скорость мотоциклиста (int S) и его позицию на дороге (int X).

Выход

В выходной поток необходимо вывести одну строку. Тут разработчики представляют нам 4 варианта:

  • ускоряться (SPEED);
  • тормозить (SLOW);
  • ехать вперед без ускорения (WAIT);
  • прыгать (JUMP).

Перевод строки на новую обязателен.

Тест 1

В начале нам представлен базовый код программы.

 

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

[su_spoiler title=»Спасательный код» icon=»arrow-circle-2″]

Мы, с чувством выполненного долга, наблюдаем как мотоциклист, с улыбкой на лице, наконец перепрыгивает первую пропасть, а затем и вторую и третью. Понимая, что мотоциклист должен прыгнуть в момент, когда пропасть будет перед ним (т.е. за 1 шаг до нее), приказываем ему ускоряться до того момента (пока расстояние до пропасти не станет равным 1 (X == R — 1)). То есть пока положение мотоциклиста Х меньше, чем расстояние до пропасти R минус длинна пропасти G (X < R — G) мотоциклист будет ускоряться. После прыжка нам нужно затормозить, то есть если положение мотоциклиста X будет уже за пропастью (X > R — G), но меньше чем конец самой дороги (X < R + G + L), он будет тормозить.

[/su_spoiler]

Подходя к 4 тесту сталкиваемся с новой проблемой. Длинна платформы для приземления очень мала и наш бессмертный каскадер вылетает за окончание дороги. Что же делать?

[su_spoiler title=»Еще более спасательный код» icon=»arrow-circle-2″]

И тут вступает в игру переменная, которую до этого момента нам не приходилось использовать в программе, а именно, скорость мотоциклиста S.

После тысячи непройденых тестов начинаешь понимать, что ты что то упустил. Вот тут то и вступает в игру всеми любимый «любимый» magic number равный, в данном случае, единице. И вправду, для того, чтобы перелететь пропасть нам потребуется скорость всего лишь на 1 больше, чем длинна этой пропасти. То есть если скорость будет равна длине пропасти + 1, то мы будем ехать с этой постоянной скоростью, в противном случае будем ускоряться. С этим замечанием программа позволяет с легкостью останавливаться на конечной платформе любой длинны.

[/su_spoiler]

Кажется, что мы предусмотрели все варианты развития событий, но не тут то было. Разработчики устанавливают новую, увлекательную задачу. Что будет, если начальная скорость будет не равна 0, спрашивают они? И мы пускаемся в глубокие размышления.

[su_spoiler title=»Код дающий, в прямом смысле, крылья» icon=»arrow-circle-2″]

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

На С++:

На Java:

 

[/su_spoiler]

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

Ю 3.14

Задача

Проверить численно второй замечательный предел:[latex]\lim_{x\to\infty}\left(1+\frac{1}{n}\right)^n=e[/latex] , задавая n значения 1,2,3…При каком n исследуемое выражение отличается от менее, чем на заданную погрешность [latex]\varepsilon[/latex]?

Тесты

[latex]\varepsilon[/latex] n Полученное e e Разность Комментарий
1.1   1  2.0000000000 2.7182818284  0.7182818284 Пройден
 0.005  271 2.7132834531 2.7182818284 0.0049983753 Пройден
0.0000000314 32890950 2.7182817970 2.7182818284 0.0000000313 Пройден
 0 Погрешность равна 0, тогда e=2.7182818284, а n=бесконечность Не пройден

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

В данной задаче необходимо было сравнить заданную погрешность [latex]\varepsilon[/latex] с разностью между числом е и полученным значением при некотором n.

Для этого в цикле высчитывалось значение формулы [latex](1+\frac{1}{n})^{n}[/latex] при [latex]n\to \infty[/latex] и находилась разность [latex]dife=e-(1+\frac{1}{n})^{n}[/latex]. Если[latex]dife>\varepsilon[/latex] , то цикл заканчивался и программа запоминала последнее значение n и после этого выводила его на экран.

Код на Java

 

А 42

Задача

Даны действительные числа [latex]x,y[/latex]  [latex](x\neq y)[/latex]. Меньшее из этих двух чисел заменить их полусуммой, а большее — их удвоенным произведением.

Тесты

Было дано Стало после проверки Комментарий
x y x y
38.76 -24.33 -1886.0615999  7.215 Пройден
11.346 23.228 17.287 527.0898 Пройден
-2444.2 1231.444 -606.378 -6019790.8496 Пройден
767.2 -1455.24 -2232920.256 -344.02 Пройден
0 213.4 106.7 0 Пройден
1111 0 0 555.5 Пройден
123.4 123.4 Ничего не выйдет, х=у Не пройден
0 0 Ничего не выйдет, х=у Не пройден

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

 

Для получения ответа переменной необходимо преодолеть критерий [latex](x\neq y)[/latex].

Если же [latex](x\neq y)[/latex], то программа сравнивает сами переменные. Тут может быть два случая:

  • Если  [latex]x>y[/latex], то начальные значения переменных мы должны изменить на [latex]x=\frac{x+y}{2}[/latex], a [latex]y=2*x*y[/latex].
  • Если [latex]y>x[/latex], то начальные значения переменных мы должны изменить на [latex]y=\frac{x+y}{2}[/latex], a [latex]x=2*x*y[/latex].

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

Второй вариант решения.

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

Для начала описываем функцию swap, которая меняет значения х и у местами. Далее, в самой программе, проверяем не равны ли х и у и, если не равны, то какое из них больше. Узнав большее, используем функцию swap.

Код на Java

Ю 2.31

Задача

График движения путников к задаче Ю 2.31


График движения путников к задаче Ю2.31

Встреча. Из пункта А в пункт В выехал велосипедист со скоростью [latex]v_{0} [/latex] км/час. Одновременно навстречу ему из пункта В двинулся «автостопом» другой путник.[latex]s_{1} [/latex] м он двигался со скоростью [latex]v_{1} [/latex] м/час, [latex]s_{2} [/latex] м — со скоростью [latex]v_{0} [/latex] км/час, [latex]s_{3} [/latex] м — со скоростью [latex]v_{3} [/latex] км/час. Через сколько часов после старта и в какой точке путники встретились?

 Тесты

v0, км/час v1, м/час v3, км/час s1, м s2, м s3, м place, км time, час Комментарии
40 15000 10 20000 40000 40000 66.667 1.667 Пройден (встреча на первом промежутке)
10 5000 60 10000 60000 30000 55.0 5.5 Пройден (встреча на первом промежутке)
8 5000 30 10000 10000 80000 37.368 4.671 Пройден (встреча на первом промежутке)
-300 30000 23333 22222 5454 555.1 Неправильно введены данные Не пройден
10 2222 3333 0 -4444 11.6 Неправильно введены данные Не пройден

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

Можно предположить, что весь путь в задаче представлен суммой [latex]ss=s_{1}+s_{2}+s_{3}[/latex]. Для начала переведем все величины  в единицы СИ:

Из метров в километры:

[latex]s_{1}=s_{1}*0.001 \Leftrightarrow s_{1}=\frac{s_{1}}{1000}[/latex],

[latex]s_{2}=s_{2}*0.001 \Leftrightarrow s_{2}=\frac{s_{2}}{1000}[/latex],

[latex]s_{3}=s_{3}*0.001 \Leftrightarrow s_{3}=\frac{s_{3}}{1000}[/latex].

Из метров/час в километры/час: [latex]v_{1}=v_{1}*0.001 \Leftrightarrow v_{1}=\frac{v_{1}}{1000}[/latex]

Найдем место встречи. Тут может быть три случая:

  1. Встреча двух путников на первом промежутке пути. Тогда время встречи можно вычислить по формуле: [latex]time = \frac{ss}{( v_{0} + v_{1} )}[/latex] , а место встречи —  [latex]place = time * v_{0}[/latex]
  2. Встреча двух путников на втором промежутке пути: Тогда время встречи можно вычислить по формуле: [latex]time =\frac{ss — s_{1} — ( v_{0} * t_{1} ) }{ v_{0} + v_{0} }[/latex] , а место встречи — [latex]place = ( t_{1} + time ) * v_{0}[/latex].
  3. Встреча двух путников на третьем промежутке пути: Тогда время встречи можно вычислить по формуле: [latex]time = \frac{ ss — s_{1} — s_{2} — ( v_{0} * t_{2} )}{ v_{0}+ v_{3} }[/latex], а место встречи — [latex] place = ( t_{1}+t_{2} + time ) * v_{0}[/latex].

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

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

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

Код на Java

 

Ю1.4

Задача.

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

Тесты

Момент начала промежутка Момент конца промежутка Ответ
Часы Минуты Секунды Часы Минуты Секунды Часы Минуты Секунды
ch min sek ch1 min1 sek1 chh  minn sekk
3 24 30 10 44 35 7 20 5
2 11 20 10 21 10 8 9 50
2 10 31 10 10 44 8 0 13
2 11 30 10 6 20 7 54 50
2 11 20 10 6 30 7 55 10
3 4 4 3 4 4 Не прошло ни секунды с начала отсчета
0 30 11 0 44 15 0 14 4
0 11 70 0 15 80 Неправильно введены данные
0 0 30 0 0 55 0 0 25

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

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

Разберем на конкретном примере. Начальный момент времени равен 2 часа 11 минут 30 секунд, а конечный — 10 часов 6 минут 20 секунд. (Строка 4 таблицы значений). Отнимая, 10-2=8, 6-11=-5, 20-30=-10, выходим за область значений и минуты с секундами получаются отрицательными. Для того, чтобы этого не случилось следует один час перевести в минуты и одну минуту перевести в секунды, то есть, соответственно, отнять единичку от конечных значений часов и минут. Получаем 9 часов 65 минут и 80 секунд. Это значение высчитывается в программе и является промежуточным вычислением, которое не выводится на экран, но участвует в расчетах. Отнимая, 9-2=7 , 65-11=54 , 80-30=50  , что уже и является результатом (7 часов 54 минуты 50 секунд). 
Остальные частные случаи вычисляются по такому же принципу (перевод одного часа в минуты / одной минуты в секунды).
Например, когда минуты начального момента времени и конечного момента времени будут равны, а секунды конечного момента времени меньше начального, то в ответе всегда получится 59 минут. (т.к. разность минут равна нулю, а одна минута нам нужна для того, чтобы оставить секунды в области допустимых значений, а 0 минут то же самое, что и 60 минут, а 60-1=59).
Второй вариант решения этой задачи выглядит намного проще. С теми же самыми тестами.

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

Алгоритм:

  1. Переводим всё в наименьшие единицы измерения (в секунды). [latex]ch*=3600 [/latex], [latex]min*=60[/latex],[latex]ch1*=3600 [/latex], [latex]min1*=60[/latex]
  2. Находим начальное значение в секундах: [latex]beg=ch+min+sek [/latex], конечное значение в секундах [latex]end=ch1+min1+sek1[/latex].
  3. Находим разность между начальным и конечным значением, тем самым находим промежуток. [latex]dif=end-beg[/latex].
  4. Вычисляем значения часов,  минут и секунд промежутка по формулам: [latex]chh = \frac{dif}{3600}[/latex], [latex]minn = \frac{dif — 3600 * chh}{60}[/latex], [latex]sekk = dif — 3600 * chh — minn * 60[/latex].

Либо еще один вариант решения при помощи операций деления и остатка от деления.

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

Алгоритм тот же кроме последнего пункта, где формулы становятся такими:
chh = dif / 3600,
minn = dif  % 3600 / 60,
sekk = dif  % 60.

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

И второе решение:

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

Код решения на Java