N-Queens(算法分析week11)

N-Queens

题目来源:https://leetcode.com/problemset/algorithms/

-题目描述-
-实现思路-
-代码实现-

题目描述

The n-queens puzzle is the problem of placing n queens on an n×n chessboard such that no two queens attack each other.
Given an integer n, return all distinct solutions to the n-queens puzzle.
Each solution contains a distinct board configuration of the n-queens’ placement, where ‘Q’ and ‘.’ both indicate a queen and an empty space respectively.

For example,
There exist two distinct solutions to the 4-queens puzzle:
[
[“.Q..”, // Solution 1
“…Q”,
“Q…”,
“..Q.”],
[“..Q.”, // Solution 2
“Q…”,
“…Q”,
“.Q..”]
]

实现思路

题目要求为给定一个棋盘的大小n,找到所有n皇后问题的解。
将棋盘存储在一个n维数组中a[n]中。数组中第i个元素的值代表第i行的皇后的位置。
判断放置一个皇后是否会产生冲突:
1、是否会产生行冲突。由于数组a中下标是唯一的,所以不会产生行冲突。
2、是否会产生列冲突。判断是否有a[i]与当前要放置皇后的列数相等就可以得到。
3、是否会产生斜线冲突。通过判断|row - i|是否与|col - a[i]|的值相等就可以得到。
得到N皇后问题所有解的过程:
1、从第0行开始,寻找每行中可以放置皇后的位置。
2、对每一行进行探测时,对行中的每一列进行分析,看是否能够放置皇后。这里有两种情况产生:
(1)如果可以,在第i行第j列放置皇后。如果i为最后一行,则得到n皇后问题的一个解,清除当前行的皇后,并从下一列重新开始探测;如果i不是最后一行,则探测下一行。
(2)如果已经探测完所有的列,都不可以放置皇后,则进行回溯,回到上一行即第i-1行,重新从a[i-1]+1列开始探测,判断能否放置皇后,如果可以,探测下一行。如果不可以则继续回溯直到可以放下皇后的一行。如果回溯到第0行仍然不能放置皇后,则已经得到所有的解。

代码实现

@requires_authorization
class Solution {
public:
    int valid(int row, int col, int n, int a[]) {
        for (int i = 0; i < n; i++) {
            if (a[i] == col || abs(i - row) == abs(a[i] - col))
                return 0;
        }
        return 1;
    }
    vector<string> solution(int a[], int n) {
        vector<string> result;
        for (int i = 0; i < n; i++) {
            string s = "";
            for (int j = 0; j < n; j++) {
                if (a[i] != j) {
                    s += ".";
                } else {
                    s += "Q";
                }
            }
            result.push_back(s);
        }
        return result;
    }
    vector<vector<string>> solveNQueens(int n) {
        vector<vector<string>> result;
        int* a = new int[1000];
        for (int i = 0; i < n; i++) {
            a[i] = -10000;
        }
        int i = 0;
        int j = 0;
        while (i != n) {
            while (j != n) {
                if (valid(i, j, n, a)) {
                    a[i] = j;
                    j = 0;
                    break;
                } else {
                    j++;
                }
            }
            if (a[i] == -10000) {
                if (i == 0) {
                    break;
                } else {
                    i--;
                    j = a[i] + 1;
                    a[i] = -10000;
                    continue;
                }
            }
            if (i == n - 1) {
                vector<string> c = solution(a, n);
                result.push_back(c);
                j = a[i] + 1;
                a[i] = -10000;
                continue;
            }
            i++;
        }
        return result;
    }
};
  • 0
    点赞
  • 0
    收藏
    觉得还不错? 一键收藏
  • 0
    评论

“相关推荐”对你有帮助么?

  • 非常没帮助
  • 没帮助
  • 一般
  • 有帮助
  • 非常有帮助
提交
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值