Это проблема из раунда квалификации Google Code Jam (которая закончилась сейчас). Как решить эту проблему?
Примечание. Если у вас есть другой метод, описанный в ответах, пожалуйста, поделитесь им, чтобы мы могли расширить наши знания о различных способах решения этой проблемы.
Minesweeper - это компьютерная игра, которая стала популярной в 1980-х годах и по-прежнему включена в некоторые версии операционной системы Microsoft Windows. У этой проблемы есть аналогичная идея, но она не предполагает, что вы играли в Minesweeper.
В этой задаче вы играете в игру на сетке одинаковых ячеек. Содержимое каждой ячейки изначально скрыто. Есть M-мины, скрытые в M разных ячейках сетки. Никакие другие клетки не содержат мины. Вы можете щелкнуть по любой ячейке, чтобы открыть ее. Если обнаруженная ячейка содержит мины, игра заканчивается, и вы проигрываете. В противном случае обнаруженная ячейка будет содержать цифру от 0 до 8 включительно, что соответствует числу соседних ячеек, содержащих мины. Две клетки являются соседями, если они разделяют угол или край. Кроме того, если обнаруженная ячейка содержит 0, то все соседи выявленной клетки автоматически обнаруживаются также, рекурсивно. Когда все клетки, которые не содержат мины, были обнаружены, игра заканчивается, и вы выигрываете.
Например, начальная конфигурация платы может выглядеть так ( "*" обозначает мину, а "c" - первая ячейка с щелчком):
*..*...**.
....*.....
..c..*....
........*.
..........
Нет никаких мин, примыкающих к клетке с щелчком, поэтому, когда она будет обнаружена, она станет 0, и ее 8 соседних ячеек также будут обнаружены. Этот процесс продолжается, в результате чего появляется следующая плата:
*..*...**.
1112*.....
00012*....
00001111*.
00000001..
В этот момент все еще не обнаружены ячейки, которые не содержат мины (обозначаются символами "." ), поэтому игроку нужно снова щелкнуть, чтобы продолжить игру.
Вы хотите выиграть игру как можно быстрее. Нет ничего быстрее, чем выигрывать одним кликом. Учитывая размер доски (R x C) и количество скрытых мин M, возможно ли (но маловероятно) выиграть одним щелчком мыши? Вы можете выбрать, где вы нажимаете. Если это возможно, то распечатайте любую действительную конфигурацию шахты и координаты вашего клика, следуя спецификациям в разделе "Вывод". В противном случае напечатайте "Impossible".
Пробованное решение:
Итак, для решения вам нужно убедиться, что каждый неминер node находится в матрице 3x3 с другими немиллионными узлами или матрицей 3x2 или 2x2, если node находится на краю сетка; позволяет называть это 0Matrix. Таким образом, любой node в 0Matrix имеет все неминные соседи.
Во-первых, проверьте, требуется ли меньшее количество мин или меньше пустых узлов
if(# mines required < 1/3 of total grid size)
// Initialize the grid to all clear nodes and populate the mines
foreach (Node A : the set of non-mine nodes)
foreach (Node AN : A.neighbors)
if AN forms a OMatrix with it neighbors, continue
else break;
// If we got here means we can make A a mine since all of it neighbors
// form 0Matricies with their other neighbors
// End this loop when we've added the number of mines required
else
// We initialize the grid to all mines and populate the clear nodes
// Here I handle grids > 3x3;
// For smaller grids, I hard coded the logic, eg: 1xn grids, you just populate in 1 dimension
// Now we know that the # clear nodes required will be 3n+2 or 3n+4
// eg: if a 4x4 grid need 8 clear nodes : 3(2) + 2
For (1 -> num 3 needed)
Add 3 nodes going horizontally
When horizontal axis is filled, add 3 nodes going vertically
When vertical axis is filled, go back to horizontal then vertical and so on.
for(1 -> num 2 needed)
Add 2 nodes going horizontally or continuing in the direction from above
When horizontal axis is filled, add 2 nodes going vertically
Например, скажем, у нас есть сетка 4x4, нуждающаяся в 8 чистых узлах, вот шаги:
// Initial grid of all mines
* * * *
* * * *
* * * *
* * * *
// Populating 3 horizontally
. * * *
. * * *
. * * *
* * * *
. . * *
. . * *
. . * *
* * * *
// Populating 2 continuing in the same direction as 3's
. . . *
. . . *
. . * *
* * * *
Другой пример: 4x4 сетка с 11 ясными узлами; Выход:
. . . .
. . . .
. . . *
* * * *
Другой пример: сетка 4x4 с четырьмя четкими узлами; Выход:
// Insert the 4 3 horizontally, then switch to vertical to insert the 2's
. . . .
. . . .
. . . .
. . * *
Теперь у нас есть сетка, которая полностью заполнена и может быть решена одним щелчком мыши, если мы нажмем (0, 0).
Мое решение работает в большинстве случаев, но оно не прошло подачу (я проверил весь файл вывода из 225 случаев), поэтому я предполагаю, что у него есть некоторые проблемы, и я уверен, что есть лучшие решения.