Задний план
Nonogram , также известный как Picross или Griddlers, представляет собой головоломку, цель которой состоит в том, чтобы определить, должна ли каждая ячейка на двумерной сетке быть цветной или оставлена пустой, используя количество последовательных цветных ячеек в каждой строке.
Ниже приведен пример головоломки Nonogram с решением.
Проблема в том, что некоторые коммерческие игры / мобильные приложения Nonogram имеют загадки, которые не могут быть решены вручную (например, имеют несколько решений или требуют глубокого возврата). Тем не менее, они также предлагают несколько жизней игроку, где одна жизнь теряется, когда вы пытаетесь закрасить ячейку, правильный ответ которой пуст . Так что теперь пришло время перебрать эти неприятные «загадки»!
Чтобы упростить задачу, представьте только одну строку с ее подсказкой и ничего больше:
3 7 | _ _ _ _ _ _ _ _ _ _ _ _ _ _ _
[3,7]
Являются ключами, а длина линии 15 сот. Поскольку у него есть несколько возможных решений, нам нужно рискнуть несколькими жизнями, чтобы полностью решить эту линию (т.е. определить все цветные ячейки).
Вызов
Учитывая строку с подсказками (список положительных целых чисел) и длину линии, найдите максимальное количество жизней, которые вы потеряете, предполагая, что вы перебираете линию с оптимальной стратегией.
Обратите внимание, что вы всегда угадываете цветные клетки . В реальных играх угадывание пустых ячеек (правильных или неправильных) не влияет на вашу жизнь, поэтому вы не можете «решить» головоломку таким образом.
Кроме того, вы можете предположить, что входные данные всегда представляют допустимую строку Nonogram, поэтому вам не нужно беспокоиться о чем-то подобном [6], 5
.
объяснение
Давайте сначала посмотрим на несколько простых примеров.
[1,2], 5
Для этой строки есть ровно три варианта ( O
цветная ячейка, .
пустая):
O . O O .
O . . O O
. O . O O
Если мы попробуем закрасить ячейку 0 (индекс на основе 0 слева), произойдет одно из следующего:
- Ячейка правильно окрашена. Теперь у нас есть две возможности, и мы можем выбирать между ячейкой 2 и ячейкой 4, чтобы полностью решить линию. В любом случае мы потеряем одну жизнь в худшем случае.
- Клетка пуста, и мы теряем жизнь. В этом случае мы уже определили уникальное решение для этой линии, поэтому мы закончили с 1 потерянной жизнью.
Следовательно, ответ для [1,2], 5
1.
[5], 10
Бинарный поиск? Нет.
Самый очевидный первый выбор - 4 или 5, который покажет одну возможность, если он пуст (по цене 1 жизни). Допустим, мы выбрали 4 в первую очередь. Если ячейка 4 действительно окрашена, мы расширяем ее влево, то есть пробуем 3, 2, 1 и 0 до тех пор, пока жизнь не будет потеряна (или ячейка 0 окрашена, и в итоге мы не тратим вообще никаких жизней). Всякий раз, когда жизнь теряется, мы можем однозначно определить решение, например, если мы увидим что-то вроде этого:
_ _ X O O _ _ _ _ _
тогда мы уже знаем ответ таков:
. . . O O O O O . .
Таким образом, ответ для [5], 10
также 1.
[3,7], 15
Начните с ячейки 11, которая, если она пуста, сразу покажет следующее решение.
O O O . O O O O O O O X . . .
Затем попробуйте 12, которое, если оно пустое, дает две возможности, которые могут быть решены ценой 1 дополнительной жизни.
O O O . . O O O O O O O X . .
. O O O . O O O O O O O X . .
Теперь попробуйте 2. Если пусто, это приводит к трем возможностям, которые могут быть решены аналогично [1,2], 5
примеру.
. . X O O O . O O O O O O O .
. . X O O O . . O O O O O O O
. . X . O O O . O O O O O O O
Если вы продолжите минимизировать риск таким способом, вы можете достичь любого решения с макс. 2 жизни потрачено.
Тестовые случаи
[1,2] 5 => 1
[2] 5 => 2
[1] 5 => 4
[] 5 => 0
[5] 10 => 1
[2,1,5] 10 => 0
[2,4] 10 => 2
[6] 15 => 2
[5] 15 => 2
[4] 15 => 3
[3,7] 15 => 2
[3,4] 15 => 3
[2,2,4] 15 => 4
[1,1,1,1,1,1,1] 15 => 2
[2,1,1,3,1] 15 => 3
[1,1,1,2,1] 15 => 5
Для последних двух случаев оптимальная стратегия - не проходить через минимальные пробелы, а просто проходить слева направо (или справа налево). Спасибо @crashoz за указание на это.
правила
Применяются стандартные правила игры в гольф . Побеждает самая короткая действительная передача в байтах.
премия
Если кто-то придумает алгоритм с полиномиальным временем (с доказательством правильности), я присуду +100 наград за такое решение.
[6], 5
?