Структуры данных → Разбор OHLC 1
03 май
Условие задачи были дополнены после контеста. И тут разбор для задачи в том виде, в котором она сейчас.
Изначально задача задумывалась как самая простая халява. Потом решил добавить пару хитростей.
Давайте сначала рассмотрим задачу чуть проще. Представим что у нас нет подпериодов и надо посчитать OHLC для всего периода (от start до end).
Тут все просто, решается в один проход. Храним 4 переменных open, high, low, close. В условии не говорится, что все данные будут из промежутка от start до end, а значит те записи которые не в промежутке можно даже не рассматривать. Считываем очередную запись сверяем с high, low, если что меняем. Самую первую запись сохраняем в open, каждую следующую в close. Это было бы правильно если бы данные были изначально отсортированы, но в условии об этом ничего не говорится. Тут есть два варианта:
- сначала сортировать входные данные
записей много, отсортировать не успеем. - или хранить дату первой и последней записи тогда каждый раз будем сравниваться с этими датами, и в случае надобности сохранять в рассматриваемую цену в open или close
Рассмотрев все записи и выводим open, high, low, close.
Теперь вернемся к реальной задаче. Считывая каждую следующую запись, надо определить к какому подпериоду она относится. Возьмем d за длительность подпериода. Если группировка по month, тогда d = 86400×7×4 = 2419200 секунд. Подпериоды считаем начиная со start. Номер подпериода записи с датой date равен x = (date - start) / d.
В условии говорится, что в результате не получится более 10000 группировок. Для каждого подпериода надо хранить шесть восьми байтных чисел: open, high, low, close, opendate, closedate. Начало подпериода хранить не нужно, так-как его легко вычислить pstart = x*d + start.
Еще надо заметить, что ограничение по памяти 2МБ. 2MB = 210241024 = 2097152 байт. В условии говорится, что в результате должно получиться не более 10000 записей. Еще если считывать все входные данные в память, то можно получить Memory Limit. 10000082+1000086 ~= 2MB. Рассмотрев одну запись, она больше не понадобится нам на протяжении всей программы, а значит не зачем ее хранить.
В условии так же говорится, что считать надо с точностью до 4 знаков. На самом деле тут нет никаких вычислений, только сравнения. Так-что можно сравнивать как обычно, главное выводить не менее 4 знаков.