八皇后(递归)

#include <iostream>
using namespace std;
class EightQueens
{
public:
    EightQueens()
    {
        count = 0;
        for (int i = 0; i < 8; i++)
            for (int j = 0; j < 8; j++)
                chess[i][j] = false;
        for (int i = 0; i < 8; i++)
            perms[i] = i;
    }
    void solve()
    {
        perm(0);
    }
private:
    int count;
    bool chess[8][8];
    int perms[8];
    void perm(int start);
    bool isSafe(int x, int y);
    void _swap(int &x, int &y)
    {
        int temp = x;
        x = y;
        y = temp;
    }
};

void EightQueens::perm(int start)
{
    if (start == 8)   //此处若改为7则出错
    {
        cout << "第" << ++count << "种情况:" << endl;
        for (int i = 0; i < 8; i++)
        {
            for (int j = 0; j < 8; j++)
            {
                if (chess[i][j])
                    cout << "*";
                else
                    cout << "-";
            }
            cout << endl;
        }
        cout << endl;
        return;
    }
    for (int i = start; i < 8; i++)
    {
        _swap(perms[start], perms[i]);
        if (isSafe(start, perms[start]))
        {
            chess[start][perms[start]] = true;
            perm(start + 1);
            chess[start][perms[start]] = false;
        }

        _swap(perms[start], perms[i]);
    }
}
bool EightQueens::isSafe(int x, int y)
{
    bool safe = true;
    int i = x, j = y;
    do
    {
        if (chess[i][j])
        {
            safe = false;
            break;
        }
        i--, j--;
    } while (i >= 0 && j >= 0);
    if (!safe) return false;
    i = x, j = y;
    do
    {
        if (chess[i][j])
        {
            safe = false;
            break;
        }
        i++, j++;
    } while (i < 8 && j < 8);
    if (!safe) return false;
    i = x, j = y;
    do
    {
        if (chess[i][j])
        {
            safe = false;
            break;
        }
        i++, j--;
    } while (i < 8 && j >= 0);
    if (!safe) return false;
    i = x, j = y;
    do
    {
        if (chess[i][j])
        {
            safe = false;
            break;
        }
        i--, j++;
    } while (i >= 0 && j < 8);
    if (!safe) return false;
    return true;
}

int main()
{
    EightQueens e;
    e.solve();
    return 0;
}

 

### 皇后问题的递归实现 皇后问题是一个经典的回溯算法问题,目标是在8×8棋盘放置皇后,使得任意两个皇后都不能互相攻击。这意味着任何两个皇后都不可以位于同一行、同一列或者同一条斜线上。 以下是基于Python语言的一种递归解决方案: #### 解决方案描述 通过递归来逐步尝试每一行中的每一个可能位置,并利用条件判断来验证当前候选位置是否合法。如果当前位置不冲突,则继续处理下一行;否则返回并重新选择新的位置。 #### 实现代码 下面提供了一个完整的Python程序用于求解皇后问题的所有可行排列方式: ```python def solve_n_queens(n): result = [] def is_safe(board, row, col): # Check this row on left side (no need as we place one queen per row) # Check upper diagonal on left side for i,j in zip(range(row,-1,-1), range(col,-1,-1)): if board[i][j] == 'Q': return False # Check lower diagonal on left side for i,j in zip(range(row,n,+1), range(col,-1,-1)): if board[i][j] == 'Q': return False return True def backtrack(board, col): if col >= n: solution = [''.join(row) for row in board] result.append(solution[:]) return for i in range(n): if is_safe(board, i, col): # If placing Queen in board[i][col] doesn't lead to conflict. board[i][col] = 'Q' # Place the Queen here backtrack(board, col + 1) # Recur to place rest of Queens board[i][col] = '.' # Backtrack and remove the Queen from current cell initial_board = [['.' for _ in range(n)] for _ in range(n)] backtrack(initial_board, 0) return result if __name__ == "__main__": solutions = solve_n_queens(8) print(f"Total number of solutions: {len(solutions)}\n") for sol in solutions[:3]: # Display first three solutions only due to space constraints for line in sol: print(line) print() ``` 上述代码中`is_safe()`函数用来检测给定坐标是否安全可放皇后,而`solve_n_queens()`则是主要逻辑所在之处,它调用了内部辅助函数来进行实际计算工作[^2]。 此版本采用列表推导式构建最终结果字符串形式以便更直观展示输出效果。同时注意这里仅打印前三个解答作为例子演示用途[^4]。 #### 关键点解析 - **安全性检查**: 需要确认新加入的位置不会威胁已存在的皇后们。 - **递归终止条件**: 当所有列都被成功填充完毕时记录当前布局状态。 - **回退机制**: 如果发现某次决策导致后续无法完成整个序列则撤销此次操作回到先前节点再次探索其它可能性路径直到找到全部符合条件的结果为止[^3]. --- ### 问题
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值