【lintcode】N皇后问题 落日映苍穹つ 2022-06-01 05:10 192阅读 0赞 n皇后问题是将n个皇后放置在n*n的棋盘上,皇后彼此之间不能相互攻击。 给定一个整数n,返回所有不同的n皇后问题的解决方案。 每个解决方案包含一个明确的n皇后放置布局,其中“Q”和“.”分别表示一个女王和一个空位置。 样例 对于4皇后问题存在两种解决的方案: [".Q..", // Solution 1 "...Q", "Q...", "..Q."], ["..Q.", // Solution 2 "Q...", "...Q", ".Q.."] 思路: * 国际象棋中皇后可以攻击同行同列以及同一斜线上的棋子,所以要以此来判断在一个棋盘格上能否放置一个皇后。我们使用一个长度为n的一维数组**Queens**来存储每一行的皇后的位置(-1表示没有皇后)。对于位置(r, c),只需判断`Queens[i] >= 0 && (Queens[i] == c || abs(r-i) == abs(c-Queens[i]))` ,若为真表示有冲突,不可放置。 * 求解过程使用回溯法,(r,c)表示当前位置 对于该位置有如下几种情况: 1.r == n-1 **a**. c == n-1(即行尾), 如果有解,则记录这个解,然后回溯到上一行的皇后之后的位置(同时删去关于该皇后的记录);否则直接回溯到上一行 **b**. 未到行尾,如果有解,则记录这个解,然后清除该行的记录,最后将c加1,移动到下一个位置;否则直接移动到下一个位置 2.r < n-1(即未到最后一行) **a**. c < n-1,即没有到行尾 如果可以放置皇后则记录相应的位置,然后令 r = r + 1, c = 0 ,移动到下一行; 否则将c加1,移动到下一个位置 **b**.c == n-1,即到达行尾 如果可以放置皇后,则记录,然后移动到下一行;否则,则回溯到上一行的皇后所在位置的后一个位置 3.在回溯的过程中可能会出现**c >= n**的情况,这时候如果 r == 0,则函数直接返回;否则回溯到上一行 代码 第一次写的题解中核心函数**solve**太过复杂,下面先提前给出一个简化过的**solve**函数。 void solve2(int r){ if(r == n){ for(int i = 0; i < n; i++) result[i][Queens[i]] = 'Q'; results.push_back(result); for(int i = 0; i < n; i++) for(int j = 0; j < n; j++) result[i][j] = '.'; } else{ for(int i = 0; i < n; i++){ for(int j = r; j < n; j++) Queens[j] = -1; if(check(r, i)){ Queens[r] = i; solve2(r+1); } } } } 完整题解如下 class Solution { vector<int> Queens; vector<vector<string> > results; vector<string> result; int n; public: /* * @param n: The number of queens * @return: All distinct solutions */ vector<vector<string> > solveNQueens(int _n) { // write your code here n = _n; Queens.resize(n, -1); result.resize(n); for(int i = 0; i < n; i++) result[i].resize(n, '.'); if(n == 1){ result[0][0] = 'Q'; results.push_back(result); return results; } else if(n < 4) return results; solve(0,0); return results; } void solve(int r, int c){ if(c >= n) if(r == 0) return; else{ r--; //删去回溯点的解 result[r][Queens[r]] = '.'; int t = Queens[r]; Queens[r] = -1; solve(r, t+1); //回溯到上一行 return; } if(r == n-1){ for( ; c < n; c++){ if(check(r,c)){ result[r][c] = 'Q'; results.push_back(result); //添加新解 result[r][c] = '.'; //删去本行的皇后 } if(c == n-1){ //若已到行尾,则回溯 r--; //删去回溯点的解 result[r][Queens[r]] = '.'; int t = Queens[r]; Queens[r] = -1; solve(r, t+1); //回溯到上一行 return; } } } else{ for( ; c < n; c++){ if(check(r,c)){ result[r][c] = 'Q'; Queens[r] = c; r++; solve(r,0); return; } if(c == n-1){ if(r == 0) return; //如果已经回溯到了第一行,则返回 else{ r--; //删去回溯点的解 result[r][Queens[r]] = '.'; int t = Queens[r]; Queens[r] = -1; solve(r, t+1); //回溯到上一行 return; } } } } } int check(int r, int c){ for(int i = 0; i < Queens.size(); i++) if(Queens[i] >= 0 && (Queens[i] == c || abs(r-i) == abs(c-Queens[i])) ) return 0; return 1; } };
相关 皇后问题 问题 > 国际象棋中的皇后,可以横向、纵向、斜向移动。如何在一个NXN的棋盘上放置N个皇后,使得任意两个皇后都不在同一条横线、竖线、斜线方向上? 举个栗子,下图的绿色格 Bertha 。/ 2022年12月06日 12:52/ 0 赞/ 181 阅读
相关 算法分析---8皇后问题---N皇后问题 ![在这里插入图片描述][20210406171121133.png] package demo1; public class NkingsSort 一时失言乱红尘/ 2022年11月16日 05:51/ 0 赞/ 178 阅读
相关 八皇后问题 一、问题描述 ![Center][] 在8x8的国际棋盘上摆放八个皇后,使其不能互相攻击,即任意两个皇后都不能同一行、同一列、同一斜线上。 八皇后问题可以扩展为n ╰+哭是因爲堅強的太久メ/ 2022年07月14日 00:17/ 0 赞/ 221 阅读
相关 八皇后问题 回溯法求解八皇后问题 n皇后问题:n皇后问题是指在一个n\n的国际象棋棋盘上放置n个皇后,使得这n个皇后两两不在同一行,同一列,同一条对角线上,求合法的方案数。 如 小灰灰/ 2022年06月11日 08:49/ 0 赞/ 274 阅读
相关 八皇后问题 枚举法 include<iostream> using namespace std; int a[9]; int check(int n, 蔚落/ 2022年06月06日 00:38/ 0 赞/ 231 阅读
相关 八皇后问题 在国际象棋中,皇后是最强大的一枚棋子,可以吃掉与其在同一行、列和斜线的敌方棋子.八皇后问题是这样一个问题:将八个皇后摆在一张8\8的国际象棋棋盘上,使每个皇后都无法吃掉别的皇 Bertha 。/ 2022年05月18日 05:58/ 0 赞/ 226 阅读
相关 N 皇后问题 n 皇后问题研究的是如何将 n 个皇后放置在 n×n 的棋盘上,并且使皇后彼此之间不能相互攻击。 给定一个整数 n,返回所有不同的 n 皇后问题的解决方案。 每一种解法包 喜欢ヅ旅行/ 2022年05月17日 04:52/ 0 赞/ 234 阅读
相关 皇后问题 八皇后问题是一个以国际象棋为背景的问题:如何能够在 8×8 的国际象棋棋盘上放置八个皇后,使得任何一个皇后都无法直接吃掉其他的皇后?为了达到此目的,任两个皇后都不能处于同一条横 绝地灬酷狼/ 2022年04月13日 12:28/ 0 赞/ 225 阅读
相关 八皇后问题 include <iostream> include <cmath> include <cstring> using namespace std 港控/mmm°/ 2022年01月31日 00:29/ 0 赞/ 296 阅读
相关 八皇后问题 八皇后问题,以国际象棋为背景:如何能够在 8×8 的国际象棋棋盘上放置八个皇后,使得任何一个皇后都无法直接吃掉其他的皇后?为了达到此目的,任意两个皇后都不能处于 叁歲伎倆/ 2021年09月25日 15:34/ 0 赞/ 463 阅读
还没有评论,来说两句吧...