C编程 - 检查游戏板的所有有效解决方案

时间:2012-04-10 01:51:53

标签: c recursion

好的,所以我要在C中创建一个代码,输出所有可能的电路板解决方案。该板是一块nxn板,其行如下(3x3):AA BA BB。

游戏的目标是通过垂直或横向穿过棋盘来访问棋盘中的每个位置。此外,如果第一个或第二个字母相同,您只能前往下一个位置,因此我可以从AA到BA,但不能从AA到BB,您只能访问每个位置一次。起始位置始终为左上角或00位置。

无论如何,我想到了一种算法,其中计算机从00开始并检查下一个有效位置,假设为01.然后计算机使用00和01链作为起始位置检查所有可能的解决方案。当没有更多时,计算机检查一个新链,让我们说00,10等等。你怎么知道不重复以前的解决方案?我正在考虑递归。是否有比我更有效的寻路算法?

2 个答案:

答案 0 :(得分:0)

Re:你怎么知道不重复以前的解决方案?

深度优先搜索算法的一部分涉及标记被访问节点,以便不访问它们两次。这可以通过多种方式完成:节点本身的备用位,在每次搜索之前初始化,或者在被搜索的图形外部的动态集数据结构。

顺便提一下,这个问题与格雷码有关,这是一种排列二进制字代码的方法,这样在连续代码之间只有一位变化。例如。 000 001 011 010 110 100 101 111.

这意味着在您的电路板中,当且仅当它是两位格雷码继承者或前任时,您​​才可以导航到相邻的广场。

但格雷码形成一个序列。所以问题是同形的,其中有一个从0到3的简单编号,并允许你从N到N + 1后继或N-1前身。

这可以帮助您思考问题。

答案 1 :(得分:0)

这是一个非常低效的Python解决方案。你应该能够跟随。我不想用你自己的语言给出答案:P

class Finder:
    def __init__(self, board, n, x, y):
        self.board = board
        self.n = n

        # Create a copy of the board.
        self.copy = []
        for i in range(n):
            row = []
            self.copy += [row]
            for j in range(n):
                row += [False]

        # The best move sequence (longest).
        self.best = []
        # The current move sequence.
        self.move = []

        self.find(x, y)

    def valid_move(self,x1, y1, x2, y2):
        # Don't move off the board!
        if x2 < 0 or x2 > self.n - 1 or y2 < 0 or y2 > self.n - 1:
            return False

        # Don't go somewhere we've gone before!
        if self.copy[y2][x2]:
            return False

        # See if this is a valid move.
        a = self.board[y1][x1]
        b = self.board[y2][x2]
        return a[0] == b[0] or \
               a[0] == b[1] or \
               a[1] == b[0] or \
               a[1] == b[1] 

    def find(self,x, y):
        self.move += [(x, y, board[y][x])]
        self.copy[y][x] = True

        # If this is the best path, then create a copy.
        if len(self.move) > len(self.best):
            self.best = list(self.move)

        # Short-circuit if the optimal route is found.
        if len(self.best) == self.n * self.n:
            return

        newX = x - 1
        newY = y
        if self.valid_move(x, y, newX, newY):
            self.find(newX, newY)

        newX = x
        newY = y - 1
        if self.valid_move(x, y, newX, newY):
            self.find(newX, newY)

        newX = x + 1
        newY = y
        if self.valid_move(x, y, newX, newY):
            self.find(newX, newY)

        newX = x
        newY = y + 1
        if self.valid_move(x, y, newX, newY):
            self.find(newX, newY)

        # Clean up by removing the last move.
        self.move = self.move[:-1]
        self.copy[y][x] = False

 # The board
board = \
[["AB", "XX", "DE"],
 ["BB", "FE", "DD"],
 ["BC", "CC", "CD"],
 ]

# The size of the board.
n = 3

# Find!!
finder = Finder(board, n, 0, 0)

for row in board:
    print(row)

# Print empty line.
print()

for move in finder.best:
    print(move)

这是输出:

['AB', 'XX', 'DE']
['BB', 'FE', 'DD']
['BC', 'CC', 'CD']

(0, 0, 'AB')
(0, 1, 'BB')
(0, 2, 'BC')
(1, 2, 'CC')
(2, 2, 'CD')
(2, 1, 'DD')
(2, 0, 'DE')