Google Code Jam round 3
Я честно старался не пройти: долго писал 1-ю задачу, забыл поменять ограничения к large-тесту 2-й задачи, не заметил четвертую вершину у треугольника в графе 3-й задачи и забил на hard 4-й, но не получилось – занял 77 место, и, как следствие, попадаю в полуфинал. К сожалению, в деле “непопадания” в полуфинал преуспели остальные казахстанские участники, так что я, похоже, поеду один
Далее – немного о задачах (полные условия лежат здесь).
Задача A. How Big Are the Pockets?
В задаче требуется посчитать суммарную площадь “карманов” простого невыпуклого прямоугольного многоугольника. Точка считается лежащей в кармане, если она не лежит в многоугольнике и выше и ниже (или левее и правее) нее есть точки границы многоугольника. Гарантируется, что никакая координата никакой точки многоугольника не превышает по абсолютному значению 3000.
Решение
Для каждой целочисленной абсциссы x найдем y1 = min(y: (x,y) принадлежит многоугольнику) и y2 = min(y: (x,y) принадлежит многоугольнику). Аналогичное действие проделаем для ординат. Теперь посчитаем площадь Sa исходного многоугольника и Sb – площадь расширенного многоугольника. Расширенным будем считать исходный многоугольник с карманами. Sa считается методом трапеций, а Sb – перебором всех клеток 1×1 принадлежащих расширенному многоугольнику. Ответом к задаче будет Sb – Sa.
Задача B. Portal
Задача на лабиринт с портальной пушкой из Portal. Ходом считается только перемещение. Создание портала ходом не считается.
Решение
В качестве состояния будем использовать координаты 3-х клеток: наше местоположение, положение первого портала и положение второго портала (если подумать, то достаточно хранить всего лишь один портал, но с заданными ограничениями все работает и так). Если построить граф между этими состояниями, то можно заметить, что в нем будут только ребра весами 1 и 0. На таком графе задачу нахождения кратчайшего пути можно решить за линейное время обходом в ширину, используя следующий трюк: если производится переход по ребру весом 0 то вершину нужно добавлять не в конец очереди, а в начало. Самое простая реализация использует list или deque из STL.
Задача C. No Cheating
В задаче требуется найти максимальное количество учеников, которое можно посадить в классе так, чтобы они не списывали. Ученик может списывать, если у него есть сосед в показанных на рисунке направлениях.
Решение
Построим граф, используя направления списывания в качестве ребер. Задача сводится к нахождению наибольшего независимого множества вершин в этом графе. В общем виде задача NP-полная, однако если присмотреться, то можно заметить, что построенный граф двудольный. А для двудольного графа количество вершин в наибольшем независимом множестве равно N – K, где N – количество вершин в графе, а K – количество ребер в наибольшем паросочетании.
Задача D. Endless Knight
Нужно посчитать, сколькими способами можно добраться ходом коня из (1, 1) в (W, H), если ходить можно только так, что обе координаты увеличиваются, и есть запрещенные клетки.
Решение
Для маленьких ограничений задача решается обычной динамикой. Для больших, возможно, нужно использовать малые ограничения на количество запрещенных клеток и считать количества путей до каждой из них и между ними. UPD: Как отметил u1ik в своем комментарии: “Да, в четвертой задаче брутфорсная формула вкл./искл. Только надо еще научиться быстро считать С(n, m) для больших чисел по модулю.”
| Print article | This entry was posted by arti on August 10, 2008 at 1:50 am, and is filed under Олимпиады. Follow any responses to this post through RSS 2.0. Вы можете оставить комментарий или трэкбэк с вашего сайта. |
Русский
English
2 года назад
Да, в четвертой задаче брутфорсная формула вкл./искл. Только надо еще научиться быстро считать С(n, m) для больших чисел по модулю.
Интересно еще в какой офис гугла отправят. Оптимизация, видимо, будет по цене билета.
2 года назад
Наверное опять в Москву
2 года назад
Жесть. Задачу C решать графами. Новое поколение программеров родит очередной С+++ и ИТ индустрия умрет от передозировки.
2 года назад
> Жесть. Задачу C решать графами. Новое поколение программеров родит очередной С+++ и ИТ индустрия умрет от передозировки.
А что, собственно Вам не нравится? Сведение задачи к стандартной, сотни раз прорешенной ранее – самый правильный и быстрый способ на мой (и не только) взгляд.
2 года назад
Задача сводится к банальному подсчету кол-вы точек в четных и нечетных столбцах. Вот это и есть самый быстрый и правильный способ решения этой задачи (незвисимо от чьих либо взглядов). Перед тем как програмить надо немного думать, поскольку варианта собсно 2. Это программирование – когда человек решает задачу оптимальным вариантом. Либо кодерство – когда человек кодирует решение “стандартными” методами. К сожалению второй вариант пользуется бешенной популярностью, даже книжки о нем пишут как мол это здорово
2 года назад
> Задача сводится к банальному подсчету кол-вы точек в четных и нечетных столбцах.
Можете показать свое решение?
> Это программирование – когда человек решает задачу оптимальным вариантом. Либо кодерство – когда человек кодирует решение “стандартными” методами.
Смотря что считать “оптимальностью”. В данных условиях и при данных ограничениях решение на графах вполне оптимально. А использование стандартных методов – это есть непереизобретение колеса.
2 года назад
имхо, спорт прога имеет свои особенности.
здесь критично время. первое правильное подходящее решение и будет оптимальным.
а париться над оптимизацией тогда, когда она не нужна, имхо, не имеет смысла.
2 года назад
Так мы дождемся гениально простого решения этой задачи, до которого не додумался, насколько мне известно, ни один из высокостоящих участников?