Фон
Рассмотрим (замкнутую) цепочку стержней, каждый из которых имеет целочисленную длину. Сколько разных полимино без дырок вы можете сформировать с данной цепью? Или, другими словами, сколько разных несамопересекающихся многоугольников с выровненными осями сторонами вы можете сформировать с данной цепочкой?
Давайте посмотрим на пример. Рассмотрим конкретную цепочку, состоящую из 8 стержней длиной 1 и 2, которые мы можем представить как [1, 1, 2, 2, 1, 1, 2, 2]
. До поворотов и трансляций есть только 8 возможных полиомино (мы учитываем разные отражения):
Этот первый стержень темно-синего цвета, а затем мы пересекаем многоугольник против часовой стрелки .
Чувство вращения не влияет на результат в приведенном выше примере. Но давайте рассмотрим еще одну цепочку [3, 1, 1, 1, 2, 1, 1]
, которая дает следующие 3 полиомино:
Обратите внимание, что мы не включаем отражение последнего polyomino, потому что это потребует обхода по часовой стрелке.
Если бы у нас была более гибкая цепочка такой же длины, [1, 1, 1, 1, 1, 1, 1, 1, 1, 1]
мы могли бы фактически сформировать оба отражения среди некоторых других полионино, всего 9:
Соревнование
Учитывая описание цепочки в виде массива или аналогичного, определите количество различных полиамино, которые вы можете сформировать (с точностью до поворотов и перемещений), используя стержни по порядку при обходе периметра в направлении против часовой стрелки.
Пожалуйста, напишите полную программу и включите команды для компиляции (если применимо) и запуска вашего кода из командной строки. Пожалуйста, включите ссылку на бесплатный компилятор / переводчик для вашего языка.
Ваша программа должна читать входные данные из STDIN. Первая строка будет содержать целое число M . Следующие M строк будут тестовыми примерами, каждый из которых будет разделенным пробелами списком длин стержней. Ваша программа должна напечатать M строк в STDOUT, каждая из которых состоит из единственного целого числа - количества различных полиомино, которые могут быть сформированы.
Вы должны использовать только один поток.
Ваша программа не должна использовать более 1 ГБ памяти в любое время. (Это не совсем строгий предел, но я буду следить за использованием памяти вашего исполняемого файла и уничтожать любой процесс, который последовательно использует более 1 ГБ, или значительно превышает его.)
Чтобы предотвратить чрезмерное предварительное вычисление, ваш код не должен быть длиннее 20 000 байтов, и вы не должны читать никакие файлы.
Вы также не должны оптимизироваться для конкретных выбранных тестовых случаев (например, путем жесткого кодирования их результатов). Если я подозреваю, что вы это делаете, я оставляю за собой право создавать новые наборы тестов. Наборы тестов являются случайными, поэтому производительность вашей программы на них должна быть репрезентативной для ее производительности при произвольном вводе. Единственное допущение, которое вам разрешено сделать, это то, что сумма длин стержней является четной.
счет
Я предоставил наборы тестов для цепей из N = 10, 11, ..., 20 стержней. Каждый набор тестов содержит 50 случайных цепочек длиной от 1 до 4 включительно.
Ваш основной балл самый большой N для которого ваша программа завершает весь набор тестов в течение 5 минут (на моей машине под Windows 8). Временной прерыватель будет фактическим временем, затраченным вашей программой на этот тестовый набор.
Если кто-то побеждает самый большой набор тестов, я буду продолжать добавлять более крупные.
Тестовые случаи
Вы можете использовать следующие контрольные примеры, чтобы проверить правильность своей реализации.
Input Output
1 1 0
1 1 1 1 1
1 1 1 1 1 1 1
1 1 1 1 1 1 1 1 3
1 1 1 1 1 1 1 1 1 1 9
1 1 1 1 1 1 1 1 1 1 1 1 36
1 1 1 1 1 1 1 1 1 1 1 1 1 1 157
1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 758
1 1 2 2 1 1 2 2 8
1 1 2 2 1 1 2 2 1 1 23
1 1 2 2 1 1 2 2 1 1 2 2 69
1 2 1 2 1 2 1 2 3
1 2 1 2 1 2 1 2 1 2 1 2 37
1 2 3 2 1 2 3 2 5
1 2 3 2 1 2 3 2 1 2 3 2 23
3 1 1 1 2 1 1 3
1 2 3 4 5 6 7 1
1 2 3 4 5 6 7 8 3
1 2 3 4 5 6 7 8 9 10 11 5
2 1 5 3 3 2 3 3 4
4 1 6 5 6 3 1 4 2
3 5 3 5 1 4 1 1 3 5
1 4 3 2 2 5 5 4 6 4
4 1 3 2 1 2 3 3 1 4 18
1 1 1 1 1 2 3 3 2 1 24
3 1 4 1 2 2 1 1 2 4 1 2 107
2 4 2 4 2 2 3 4 2 4 2 3 114
Вы найдете входной файл с этим здесь .
Leaderboard
User Language Max N Time taken (MM:SS:mmm)
1. feersum C++ 11 19 3:07:430
2. Sp3000 Python 3 18 2:30:181
источник
Ответы:
C ++ 11
Обновления: добавлена первая строка,
c
которая начинается раньше, если расстояние слишком далеко от начала координат (что и было целью переменнойrlen
, но я забыл написать ее в первой версии). Я изменил его, чтобы использовать гораздо меньше памяти, но ценой времени. Теперь он решает N = 20 всего за 5 минут для меня.Компилировать с
источник
#define
s thoPython 3 (с PyPy ) - N = 18
Беги с
./pypy <filename>
.Это эталонная реализация, которую я написал при обсуждении вопроса с Мартином. Он не был сделан с учетом скорости и довольно хакерский, но он должен обеспечить хорошую основу для начала.
N = 18 занимает около 2,5 минут на моем скромном ноутбуке.
Алгоритм
Вращения проверяются путем преобразования каждой фигуры в серию
F
для прямого,A
для вращения против часовой стрелки иC
для вращения по часовой стрелке в каждой точке решетки на границе формы - я называю это угловой строкой . Две формы вращательно идентичны, если их угловые струны являются циклическими перестановками. Вместо того, чтобы всегда проверять это, сравнивая две угловые строки напрямую, когда мы находим новую форму, мы преобразуем ее в каноническую форму перед сохранением. Когда у нас появляется новый кандидат, мы конвертируем в каноническую форму и проверяем, есть ли у нас это уже (таким образом, используя хеширование, а не перебирая весь набор).Строка угла также используется, чтобы проверить, что форма сформирована против часовой стрелки, убедившись, что число
A
s превышает числоC
s на 4.Самопересечение наивно проверяется путем сохранения каждой точки решетки на границе фигуры и проверки, если точка посещена дважды.
Основной алгоритм прост: поместите первый стержень вправо, а затем опробуйте все возможности для оставшихся стержней. Если стержни достигают точки, которая находится слишком далеко от начала координат (т. Е. Сумма оставшихся длин стержней меньше, чем манхэттенское расстояние точки от начала координат), то мы преждевременно прекращаем поиск этого поддерева.
Обновления (последние сначала)
источник