e-olymp 57. Бабочка-санитар

Задача взята с сайта e-olymp.com.
Решение на с++

Условие

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

Мурзик всегда следил за чистотой школьного двора и ему в этом с радостью помогали бабочки, благодарные за прекрасные фотографии, сделанные им. Бабочки могли использовать собственные крылышки как линзы, причем они могли изменять их фокусное расстояние. Заметив обертку от конфетки, лежавшую на школьном дворе в точке с координатами [latex]X_1[/latex], [latex]Y_1[/latex], бабочка перелетала в точку с координатами [latex]X_2[/latex], [latex]Y_2[/latex], [latex]Z_2[/latex], расположенную на пути солнечных лучей к обертке и, изменяя фокусное расстояние своих крылышек-линз, сжигали обертку от конфеты.

Какую оптическую силу [latex]D[/latex] имели крылышки-линзы бабочки в этот момент?

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

В первой строке 2 числа: координаты [latex]X_1[/latex], [latex]Y_1[/latex] обертки от конфетки. Во второй – 3 числа: координаты [latex]X_2[/latex], [latex]Y_2[/latex], [latex]Z_2[/latex] бабочки в момент сжигания обертки.

Все входные данные целые числа, не превышающие по модулю 1000.

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

Единственное число – оптическая сила крылышек-линз [latex]D[/latex].

Код

Ход решения:

Вычисляем оптическую силу линзы [latex]D[/latex] по формуле [latex]D=\frac{1}{f}
[/latex], где [latex]f[/latex] — расстояние между бабочкой и обёрткой. Вычисляем его по формуле: [latex]f =
\sqrt{(X_2-X_1)^2+(Y_2-Y_1)^2+Z_2^2}[/latex].

e-olymp 138. Банкомат

Ссылка на условие задания: e-olymp.

Условие

В банкомате имеются в достаточном количестве купюры номиналом $10$, $20$, $50$, $100$, $200$, $500$. Найти минимальное количество купюр, которое необходимо использовать, чтобы выдать сумму в $n$ гривен или вывести $-1$, если указанную сумму выдать нельзя.

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

Одно число $n$ ([latex]1 \leq n \leq 1000000[/latex]).

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

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

Тесты

Входные данные Выходные данные
Сумма Количество купюр
130 3
999 -1
7360 18
440 4
3 -1

Код.

Решение.

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

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

Следует учесть, что сумма может быть и такой, что банкомат не сможет ее выдать. Это будет происходить тогда, когда сумма содержит некоторую часть, меньшую самой меньшей купюры. Для проверки этого условия, до начала выполнения жадного алгоритма, выполняется проверка. Если указанная сумма делится на 10 без остатка, то функция начинает выполнение алгоритма, если же нет, то возвращает $-1$.

Ссылка на решение задачи на сайте Try Haxe!

e-olymp 915. Прямоугольный или нет?

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

Задано длины сторон треугольника. Определить, является ли этот треугольник прямоугольным.

Ссылка на задачу на e-olimp.

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

В единственной строке задано 3 натуральных числа — длины сторон треугольника. Длины сторон не превышают 1000.

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

Вывести «YES» (без кавычек), если треугольник прямоугольный, или «NO» (без кавычек) в противном случае.

Решение

Для проверки вида треугольника использовалась формула из теоремы Пифагора : $$a^2+b^2=c^2,$$ где — $a$ и $b$ — катеты, $c$ — гипотенуза.

Тесты

Входящие данные Результат
5, 4, 40 NO
6, 10, 2 NO
5, 4, 3 YES
3, 4, 5 YES

Пример на TryHaxe.

e-olymp 111. Часы

Ссылка на условие задания: e-olymp.

Условие

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

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

Начальное и конечное время одних календарных суток в часах ($H$) и минутах ($M$) через пробел ([latex]0 \leq H \leq 23, 0 \leq M \leq 59[/latex]).

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

Ответ на задачу.

Тесты

Входные данные Выходные данные
Начальное и конечное время Количество ударов
13 30 15 10 7
0 00 23 59 180
12 30 12 30 1
22 22 22 25 0

Код.

Решение.

Заведем переменную, которая будет отвечать за количество пробитых ударов res. Если на часах 59 минут, то увеличиваем количество часов h1, и обнуляем значение минутной стрелки m1, для следующего круга. Если значение минутной стрелки равно 30 то увеличиваем переменную res на один. Если же минутная стрелка на 12, то есть 0 минут, то к res добавляем остаток от деления текущего количества часов на 12. Увеличиваем значение переменной m1 на 1. Повторяем, пока начальное время не будет совпадать с конечным.
Ссылка на решение задачи на сайте Try Haxe!

Альтернативное решение.

Также существует способ решения этой задачи без использования циклов. Для этого я использовала функцию FactTree, которая реализует арифметическую прогрессию. Эта функция считает сколько ударов совершили часы от 0 часов, до указанного в качестве параметра времени. Объясним принцип работы функции ProdTree.Пусть нам нужно найти сумму последовательных чисел от L до R, обозначим его как P(L, R). Разделим интервал от L до R пополам и посчитаем P(L, R) как P(L, M) + P(M + 1, R), где M находится посередине между L и R, M = (L + R) / 2. Заметим, что слагаемые будут примерно одинаковой длины. Аналогично разобьем P(L, M) и P(M + 1, R). Будем производить эту операцию, пока в каждом интервале останется не более двух слагаемых. Очевидно, что P(L, R) = L, если L и R равны, и P(L, R) = L + R, если L и R отличаются на единицу.

Ссылка на решение задачи на сайте Try Haxe!

e-olymp 126. Номер квартиры

Ссылка на условие задания: e-olymp.com

Условие

Многоквартирный дом имеет $N$ квартир, $P$ подъездов и $Q$ этажей, причем на каждом этаже каждого подъезда имеется одинаковое количество квартир. Определить в каком подъезде и на каком этаже находится квартира с заданным номером.

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

Значения $N$, $P$, $Q$, $K$, причем [latex]1 \leq K \leq N \leq 1000[/latex], [latex]P \cdot Q \leq N[/latex].

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

Нужно вывести номер подъезда и этаж, на котором находится квартира с номером $K$.

Тесты

Входные данные Выходные данные
250 5 5 1 1 1
30 2 5 27 2 4
300 3 10 111 2 2
80 5 4 77 5 4

Код.

Try Haxe!

6.6 Array Comprehension

Array Comprehension – это выражение, которое позволяет быстро создавать новый массив из существующего с помощью for и while, или без массива с инициализацией переменных во время итераций цикла.

Простые array comprehensions:

Array Comprehension с использованием if:

Array Comprehension c использованием двух массивов:

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

Также можно инициализировать массив после его объявления:

Ссылка на официальную документацию

2.3.2 Наследование

Source: 2.3.2 Inheritance
Как во многих объектно-ориентированных языках, классы в языке Haxe являются основной структурой данных для большинства программ. Класс объявляется с помощью ключевого слова class . В классе может быть ноль или более полей класса. Пример класса Ogr, который представляет собой создание экземпляра класса Ogr, с полем life типа Int:

Экземпляр класса создается с помощью ключевого слова new:

Здесь метод toString() отображает представление экземпляра класса Ogr.

В Haxe классы могут наследовать от других классов, это осуществляется с помощью использования ключевого слова extends:

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

Вышеприведенный код класса Warrior очень похож на исходный код родительского класса Ogr, но в нем появляются две новые конструкции:

  • extends Ogr обозначает, что этот класс наследует класс Ogr
  • super (x, y) — вызывает конструктор родительского класса, в данном случае Ogr.new
  • override переопределяет метод toString()  родительского класса   Ogr

Для дочерних классов не обязательно определять собственные конструкторы, но если они есть, вызов super () является обязательным. В отличие от некоторых других объектно-ориентированных языков, этот вызов может появляться в любом месте кода конструктора и не обязательно должен быть первым выражением.

Создается экземпляр класса Warrior таким образом:

Где видно, что когда класс наследует другой класс он становится подтипом родительского класса, т.е. каждый экземпляр Warrior также является и экземпляром типа Ogr.

Подробнее про эффекты и ограничения переопределяющих методов можно прочитать в Overriding Methodsе.

ML30. Объём параллелепипеда

Задача взята отсюда
Условие
Найти объём параллелепипеда три стороны которого образованы векторами:
$$\overrightarrow{a}=(a_x,a_y,a_z), \overrightarrow{b}=(b_x,b_y,b_z), \overrightarrow{c}=(c_x,c_y,c_z).$$
Входные данные: Координаты векторов $\overrightarrow{a}, \overrightarrow{b}, \overrightarrow{c}.$
Выходные данные: Объём параллелепипеда.

Тесты

Входные данные Выходные данные
0 0 1 0 1 0 1 0 0 1
0 0 0 1 0 0 0 0 1 0
1 0 0 0 0 1 0 0 1 0
2 5 3 4 1 0 -2 7 6 18
3 5 1 0 -7 2 6 -4 5 21

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

Решение

Для решения данной задачи можно составить матрицу и вывести из неё формулу для нахождения определителя:
$$\triangle = \begin{vmatrix}a_{x} & a_{y} & a_{z}\\b_{x} & b_{y} & b_{z}\\c_{x} & c_{y} & c_{z}\end{vmatrix} = $$ $$= a_{x} \times ((b_{y} \times c_{z}) + (c_{y} \times b_{z}))-a_{y} \times ((b_{x} \times c_{z})+ $$ $$+(c_{x} \times b_{z})) + a_{z} \times ((b_{x} \times c_{y})+(c_{x} \times b_{y}).$$
Модуль определителя матрицы равен объёму параллелепипеда.
Ссылка на запуск программы.

7. Использование Компилятора

Ссылка на оригинальную статью.

Основное использование
Компилятор Haxe обычно вызывается из командной строки с несколькими аргументами, которые должны отвечать на два вопроса:

  • Что должно быть скомпилировано?
  • Каким должен быть результат?

Чтобы ответить на первый вопрос, обычно достаточно указать путь к классу через аргумент -cp path вместе с основным классом, который должен быть скомпилирован с помощью аргумента -main dot_path. Компилятор Haxe затем выбирает основной файл класса и начинает компиляцию.

Второй вопрос обычно сводится к предоставлению аргумента, указывающего желаемый результат. Haxe имеет выделенный переключатель командной строки, такой как -js имя_файла для JavaScript и -php для PHP. В зависимости от характера цели значение аргумента представляет собой либо имя файла (для -js, -swf и neko), либо путь к каталогу.

Общие аргументы
Ввод:

  • -cp path — добавляет путь к классу, в котором могут быть найдены .hx исходные файлы или пакеты (подкаталоги).
  • -lib library_name — добавляет библиотеку Haxelib. По умолчанию используется самая последняя версия в локальном репозитории Haxelib. Чтобы использовать определенную версию, можно использовать -lib library_name: version.
  • -main dot_path — устанавливает основной класс.

Вывод:

  • -js имя_файла — генерирует исходный код JavaScript в указанном файле.
  • -as3 directory — генерирует исходный код ActionScript 3 в указанной папке.
  • -swf file_name — создает указанный файл как Flash.swf.
  • -neko file_name — генерирует двоичный файл Neko в качестве указанного файла.
  • -php directory — генерирует исходный код PHP в указанной директории.
  • -cpp directory — создает исходный код C++ в указанном каталоге и компилирует его с использованием собственного компилятора C++.
  • -cs directory — создает исходный код C# в указанной директории.
  • -java directory — создает исходный код Java в указанном каталоге и компилирует его с помощью компилятора Java.
  • -python имя_файла — генерирует исходный код Python в указанном файле.

ML 35. Бильярдные шары

Ссылка на условие задания: cpp.mazurok.com

Условие

Для аккуратной расстановки шаров в «пирамидку» игроки в бильярд используют специальный равносторонний треугольник. Вычислите какое наибольшее количество шаров радиуса $r$ можно расставить на бильярдном столе при помощи треугольника со стороной $a$.

Изображение

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

Длина стороны $a$, и радиус шаров $r$.

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

Число $n$, количество шаров.

Код.

Решение.

Для решения данной задачи нужно понимать что каждый шар занимает пространство вокруг себя которое равняется площади описанного вокруг данного шара треугольника. Чтобы посчитать количество шаров вмещаемых в треугольник надо воспользоваться формулой площади равностороннего треугольника через сторону для большого треугольника [latex]S = \frac{a^2\sqrt{3}}{4}[/latex] , и соответственно формулой площади треугольника в который вписан круг основываясь на радиус [latex]S1 = 3\sqrt{3}x^2[/latex] В результате деления данных формул получим количество шаров радиуса $r$ которые поместятся в Треугольника со стороной $a$.

Ссылка на решение задачи на сайте Try Haxe!