Блог пользователя pkhaustov

Автор pkhaustov, 13 лет назад, По-русски
Задача A. Футбол
Классическая задача A второго дивизиона. Можно было решить без хранения в памяти всех N строк входного файла. Хотя тесты проходило и любое решение, которое только можно себе представить.
Решение без сохранения всех N строк в памяти: считывать все строки, при встрече незнакомой строки присваивать ей идентификатор. Для каждого идентификатора завести счетчик, который будет отражать, сколько раз строка встретилось во входном файле. Из двух строк выбрать ту, у которой значение счетчика больше.

Задача B. Письмо
Самое простое решение - это для каждой буквы (другие символы просто игнорировать) в обеих строках посчитать число ее вхождений. Если какая-то буква входит во вторую строку большее число раз, чем входит в первую, ответ "NO", иначе ответ "YES". Очевидная асимптотика решения O(L), где L - ограничение на длину строки во входном файле.

Задача С. Счастливые билеты
Всем известно условие делимости числа на 3: "Число кратно трем, тогда и только тогда, когда сумма цифр этого числа делится без остатка на 3". Соответственно, чтобы при склеивании двух чисел получить число кратное трем, необходим чтобы сумма цифр первого числа плюс сумма цифр второго числа было кратно трем.
Стоит отметить, что оперировать в условиях этой задачи можно только с остатками от деления на 3. Несложно понять, что есть смысл соединять числа, которые дают в остатке от деления на 3 двойку с теми, кто дает в остатке единицу. Числа, которые нацело делятся на 3 можно объединять только с числами, которые так же делятся нацело на 3. Если посчитать количество чисел на кусках билетов с остатком от деления на 3 равным 0, 1, 2 (обозначим их как R0, R1, R2 соответственно), то ответом будет min(R1, R2) + [R0 / 2]. Здесь [] - операция округления в меньшую сторону.

Задача D. Путешествие
Задача не требует знания каких-то алгоритмов, математики или даже банальной логики. От Вас требуется найти все частные случаи и не забыть рассмотреть каждый из них.
Теста "1 1" быть не могло (ограничения такие).
Для тестов "1 2" и "2 1" ответом служит последовательность из трех клеток (1 1, оставшаяся клетка, 1 1). Телепортов не требуется.
Для тестов "1 M" и "N 1" (2 < N, M) ответом служит последовательность 1 1 -> 1 2 -> ... -> 1 M (ну и аналогично для перевернутого случая) и снова 1 1 в конце. Требуется один телепорт (1 M -> 1 1).
Далее логика простая. Если хотя бы одна из сторон - четная, то пройти можно следующим алгоритмом:
Рассмотрим случай, когда количество строк нечетно. При нечетном количестве столбцов можно действовать так же, поменяв строки и столбцы местами.
Из клетки 1 1 шагнем в 1 2 и далее пойдем змейкой по прямоугольнику Rect(1, 2, N, M). То есть во время обхода змейкой не посещаем первую строку. Такой обход закончится в клетке с координатами 2 M. После чего можно шагнуть на 1 M и спокойно прийти по первой строке в 1 1.
Для случая, когда N и M четные, можно воспользоваться тем же алгоритмом. Очевидно, что телепортов строить во всех этих случая не потребуется.
Для случая, когда N и M нечетные всегда потребуется один телепорт. Если действовать по той же стратегии, то в конце обхода змейкой можно попасть только в клетку с координатами N M, откуда необходимо телепортироваться в клетку 1 M и пройтись по первой строке до клетки 1 1.

Задача E. Гонка
Задача не требует знания каких-то сложных формул из физики. Сразу открою занавесу и выпишу все формулы, которые потребуются при решении.
X0 = 0
Xn + 1 = Xn + Vn (Tn+1 - Tn), где Xi - координата, Ti - момент времени
Несложно понять, что решение с асимптотикой O(SN2) получит заслуженный Time Limit. Решение с асимптотикой O(KN3) вполне сойдет. Впрочем, скорее всего существует решение с гораздо более хорошей трудоемкостью.
Далее будет рассказано решение за O(KN3), которое имеет множество других достоинств.
Будем рассматривать всю гонку, как набор некоторых событий упорядоченных во времени. События - изменение скорости какого-либо участника в какой-либо момент времени. Для каждого участника несложно (еще при чтении) получить все события, которые с ним связаны. Каждое из них обладает двумя параметрами: время, когда была сменена скорость и сама величина скорости. Все события можно объединить и упорядочить хронологически (в порядке неубывания времени, когда происходит событие).
Теперь нет смысла идти по всем моментам времени (от 0 до S). Есть смысл рассматривать только моменты времени, в которые происходит хотя бы одно событие. Всего смен скоростей будет O(NK). Для дальнейшего решения можно сделать несколько утверждений:
Между двумя соседними моментами времени (в которые происходят события) скорости автомобилей остаются постоянными. Соответственно, автомобиль i обгонит на участке между этими двумя моментами времени автомобиль j если Vi > Vj (иначе обгон точно не возможен). А далее требуется соблюдение одного из двух условий:
  • Координата автомобиля i в первый момент времени меньше, чем у автомобиля j, а во второй момент времени координата автомобила i уже больше координаты автомобиля j.
  • Координата автомобиля i в первый момент времени такая же, как у автомобиля j, а во второй момент координата автомобиля i больше координаты автомобиля j. При этом на предыдущем этапе координата автомобиля i была меньше (то есть он сравнялся с автомобилем j на прошлом интервале времени).
На каждом временном интервале можно за O(N2) проверять для каждой пары (i, j) обгоняет ли автомобиль i автомобиль j.
Каждое из вышеописанных условий можно проверить в целых числах (32 бита вполне хватает). Ответ так же не потребует 64-битовой переменной.
Стоит отметить, что решение не использует значение S, которое дается во входном файле.  Дописав один IF можно получить решение, которое будет правильно обрабатывать даже случаи, когда автомобили некоторое время ехали бок о бок.
Разбор задач Codeforces Beta Round 42 (Div. 2)
  • Проголосовать: нравится
  • +5
  • Проголосовать: не нравится

13 лет назад, # |
  Проголосовать: нравится +9 Проголосовать: не нравится
Спасибо товарищу xcr за то, что он заметил интересный факт. Если смотреть на задачу E согласно условию, то если машины сравнялись в момент времени T, а затем одна ускорилась и ушла вперед, то обгоном это можно назвать только если до этого машина, которая ушла вперед была позади. Такое можно проверить тестом:
2 5
3 2 1 1 1 2 1
3 1 1 2 1 1 2
Здесь обгона произойти не должно, а если взять вот такой тест:
2 7
4 2 1 1 2 1 1 2 1 
4 1 2 2 1 2 1 1 1
Тут происходит ровно один обгон.
Мое решение, которое выдавало ответ 1 на оба этих теста получало Полное решение. Если же исправить на понимание, при котором ответ на первый тест равен нулю, то мое решение получает Неправильный ответ на тесте 23.
Интересно, что думают авторы контеста по этому поводу.
  • 13 лет назад, # ^ |
      Проголосовать: нравится +3 Проголосовать: не нравится
    Я как раз обрабатывал такой случай, и мое решение упало на 23-ем тесте. Убрав проверки, получил accepted. Исходя из условия, такое решение неверно. Там явно сказано "обгоном считается ситуация, когда одна машина догоняет и опережает другую".
13 лет назад, # |
Rev. 2   Проголосовать: нравится 0 Проголосовать: не нравится
Я так бегло посмотрел результаты. Достаточно людей написали решение, которое упало на тесте номер 23. Среди них Egor, который вполне бы мог быть на первом месте, если бы у него прошла задача E. На мой взгляд решение жюри не соответствует условию.
13 лет назад, # |
  Проголосовать: нравится 0 Проголосовать: не нравится
К сожалению, я сдал Е только после конца контеста(да я лох =) ), но вроде мое решение работает за O(N*N*K) и получила ОК. 
Нам не обязательно обрабатывать все N*K событий для всех пар машин(N*N). Можно для каждой пары машин, проверить кол-во пересечений между ними за O(K) и просуммировать их( естественно пары машин уникальны). Получим ответ. Как-то так.
  • 13 лет назад, # ^ |
      Проголосовать: нравится 0 Проголосовать: не нравится
    Действительно хорошая идея решения за O(N2K). Причем, если правильно организовать проверку для каждой пары автомобилей, то проверка будет такая же как и в описанном выше решении. В таком случае тоже несложно написать решение, которое не особо беспокоится о том, ехали ли машины какое-то время бок о бок. Впрочем, условие на эту задачу вызывает уже уйму вопросов.
13 лет назад, # |
  Проголосовать: нравится 0 Проголосовать: не нравится
Хотя мое первое решение было таким как написано в разборе.