Прошел уже девятый сезон тренировок от Yandex. В этот раз изменили формат: раньше на целую неделю давалось ~10 задач на одну тему, которые можно было решать в любое время. Сейчас каждую неделю выделяли четыре слота по часу вечером, в каждом по две задачи. Такой формат ближе к спортивному программированию и собеседованиям. Дополнительно каждую неделю предлагался набор задач вне конкурса.

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

В прошлый раз я почти подобрался к заветному 300 месту за которое дают плюшки. Сейчас получилось плюс-минус также, я сдал все задачи в зачет с плюса, кроме одной. Основная моя проблема - низкая скорость решения. Это подтверждает и тот факт, что в части контестов вне зачета я дорешивал вторую задачу уже после дедлайна, примерно через полчаса.

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

Для меня самым полезным оказалось порешать задачи на префиксные суммы и стек рекордов. Концепцию префиксных сумм понять несложно, но применять их последовательно в одной задаче трудновато. Каноничный пример, посчитать сумму произведений по всем тройкам индексов: ∑i<j<k ai·aj·ak.

Решение можно построить за линейное время за три цикла. Считаем сначала суффикс сумм p_sum от n до 0. Вторым шагом используя посчитанный суффикс для подсчета второго, как p_muli = p_muli+1 + p_sumi+1· ai, так же идя в обратном направлении. Последним шагом идем в прямом направлении и все суммируем, домножая на ai.

Чтение данных

Самая полезная функция на контесте – это считывание данных. В C++ все просто работает через <</>>, в Rust приходится городить буфер и самому разделять по пробелам:

fn get_ints<T: std::str::FromStr>(n: usize) -> Vec<T> {
    let mut s = String::new();
    std::io::stdin().read_line(&mut s).unwrap();
    s.split_whitespace()
        .take(n) // можно убрать, если нужно считать все до конца строки без указания количества
        .map(|w| w.parse().ok().unwrap())
        .collect()
}
let [n, k] = get_ints::<usize>(2).try_into().unwrap();
let v = get_ints::<usize>(n);

// Считывание строки тоже пригождается
let mut s = String::new();
std::io::stdin().read_line(&mut s).unwrap();
let s = s.trim_end();

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

cert yandex 9.0

Метки:

Разделы:

Дата изменения: