Задача с замощением прямоугольной области L образной плиткой

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

Примеры:
1. Ввод - L = 3, W = 4
Вывод - 4

2. Ввод - L = 69, W = 2
Вывод - 8388608

Мои попытки решения задачи заключались в создании двумерного массива заполненного нулями, затем полным перебором и проверкой всех вариантов на присутствие нулей, но увы.
  • Вопрос задан
  • 3660 просмотров
Решения вопроса 2
@encyclopedist
Для решения задач о покрытии есть специальный "Алгоритм X" Дональда Кнута.
На хабре есть хорошая статья на эту тему: habrahabr.ru/post/194410
Ответ написан
@Rapt Автор вопроса
На другом форуме мне ответили как решить эту задачу комбинаторно, вот код:
# length % 3 = 0; width % 2 = 0
def calculate(length, width):
    degree = (length / 3) * (width / 2)
    print(2 ** degree)
 
if __name__ == "__main__":
    length = input("Enter L: ")
    width = input("Enter W: ")
    
    length = int(length)
    width = int(width)
    
    if length % 3 == 0:
        if width % 2 == 0:
            calculate(length, width)
        else:
            raise AssertionError("Wrong data!")
    elif length % 2 == 0:
        if width % 3 == 0:
            calculate(width, length)
        else:
            raise AssertionError("Wrong data!")
    else:
        raise AssertionError("Wrong data!")
    input()


Площадь двух соединённых плиток 2*3=6 можно взять за единицу, причём плитки могут соединятся двумя способами, а следовательно каждая полученная единица площади может принимать 2 состояния. Число всех состояний для двух единиц 2*2, для трёх 2*2*2 (формула комбинаторики для размещения из n по m), то есть в итоге 2 в степени количества единиц. Переменной degree присваивается количество данных единиц, после чего выводится 2 в степени degree.

Также спасибо @encyclopedist за познавательную статью! По ней сделать решение будет намного интересней!
Ответ написан
Комментировать
Пригласить эксперта
Ответы на вопрос 1
qmax
@qmax
программер
Можно попробовать заполнять обасть по рядам.
Каждый ряд разбивать на отрезки (длинной 1 или 2), относящиеся к одной плитке.
Каждое заполнение будет порождать ограничения (шаблон) для заполнения следующего ряда.

Конкретно, каждый новый (не из шаблона) отрезок порождает для следующего ряда два варианта заполнения в смежных клетках.

[_][2][2][_]
[_][1][_][_]

[_][2][2][_]
[_][_][1][_]

[_][_][1][_][_]
[_][2][2][_][_]

[_][_][1][_][_]
[_][_][2][2][_]

Ну только хранить это надо чуть хитрее, чем просто клеточки.
Ответ написан
Ваш ответ на вопрос

Войдите, чтобы написать ответ

Войти через центр авторизации
Похожие вопросы