N-Queens 回溯/递归逻辑错误?
Posted
技术标签:
【中文标题】N-Queens 回溯/递归逻辑错误?【英文标题】:N-Queens Backtracking/Recursion Logic Errors? 【发布时间】:2018-03-30 02:24:27 【问题描述】:我正在尝试解决这个问题,作为我即将进行的测试的练习。它要求我用 C++ 编写一个程序,要求输入“棋盘大小”(nxn)和“皇后数”,然后执行“n 皇后”问题。
这个 n-queens 问题与“正常”n-queens 问题的不同之处在于,皇后的数量和棋盘大小可以变化,如果棋盘没有完全填满,则开放空间被替换了。
输入大小为“8”和皇后号“4”的示例输出如下所示:
O.......
..O.....
....O...
.O......
...-...-
........
...-.-..
...-..-.
其中“O”代表一个被皇后占据的空间,“.”表示被另一个皇后挡住的空间,'-' 表示如果用户输入了更多数量的皇后(即开放空间),则 可能被另一个皇后占据的空间。
问题是,我已经把问题编码出来了,它给了我极度不一致的结果。 (例如:输入 4,4 个作品,5,5 个作品,6,6 个不工作,7,7 个作品,8,8 个不工作,2 ,1 不工作....这个列表还在继续)。我发现罪魁祸首是“for”循环和完成后返回堆栈的递归的组合,根据情况导致了几个错误。我的问题是,我将如何修复递归循环,以便它仍然能够回溯,同时也不会不必要地导致错误?我对“回溯”加上递归的想法很陌生;以后我可以做些什么来改进我的回溯方法?
我的代码如下:
#include <iostream>
#include <cstdlib>
using namespace std;
void readBoard(char board[100][100], int size);
void printBoard(char board[100][100], int size);
bool findOpenSpot(char board[100][100], int row, int col, int size);
bool nQueenSolver(char board[100][100], int row, int size, int queenNumber);
int main()
int queenNumber;
int size;
char b[100][100];
cout << "What size board do you want?" << endl;
cin >> size;
readBoard(b, size);
printBoard(b, size);
cout << "How many queens do you want to place?" << endl;
cin >> queenNumber;
if (queenNumber > size)
cout << "Impossible." << endl;
exit(0);
if (nQueenSolver(b, 0, size, queenNumber) == true)
printBoard(b, size);
else
cout << "Impossible." << endl;
return 0;
bool nQueenSolver(char board[100][100], int row, int size, int queenNumber)
if (row >= size)
return true;
for (int j=0; j<size; j++)
if (findOpenSpot(board, row, j, size) == true)
if (queenNumber >= 0)
board[row][j] = 'Q';
cout << "Subtracting one queen." << endl;
else if (queenNumber < 0)
board[row][j] = '-'; //If all queens have already been placed, start showing open slots.
if (nQueenSolver(board, row+1, size, queenNumber) == true) //Recursion to cycle down the rows
return true;
board[row][j] = '.'; //Backtracking if needed.
return false;
bool findOpenSpot(char board[100][100], int row, int col, int size)
int i, j;
for (i=0; i<col; i++)
if (board[row][i] == 'Q') //Checks if there's any queens to the left of the index
return false; //Not an open spot.
i = row; j = col;
while (i >= 0 && j >= 0)
if (board[i][j] == 'Q') //Checks if there's any queens in the upper left diagonal of the index
return false;
i--; j--;
for (i=0; i<row; i++)
if (board[i][col] == 'Q') //Checks if there's any queens on top of the index
return false;
i = row; j = col;
while (i >= 0 && j >= 0)
if (board[i][j] == 'Q') //Checks if there's any queens in the upper right diagonal of the index
return false;
i--; j++;
return true; //This index isn't threatened by a queen, go ahead and place one here!
//Open spot!!
void readBoard(char board[100][100], int size)
for (int i=0; i<size; i++) //Puts in the size of the board into the array.
for (int j=0; j<size; j++)
board[i][j] = '.';
void printBoard(char board[100][100], int size)
for (int i=0; i<size; i++) //Prints the 'board' part of the array. (Doesn't print the entire array)
for (int j=0; j<size; j++)
cout << board[i][j];
cout << endl;
我也尝试在网上寻求帮助,但没有找到任何帮助(在 *** 和谷歌上。只有我已经使用过的信息片段)。任何帮助将不胜感激!! :)
【问题讨论】:
【参考方案1】:findOpenSpot
(最后一个 while 循环)中的“右上角”检查条件不正确。由于您在该循环中递增 j
,因此您需要检查 j
是否低于数组的上限,而不是与零进行比较。
while (i >= 0 && j < size)
这也将使用当前未使用的size
参数。如果您以足够高的警告级别进行编译,编译器会告诉您size
是一个未使用的参数,这将是一个有问题的线索。
【讨论】:
以上是关于N-Queens 回溯/递归逻辑错误?的主要内容,如果未能解决你的问题,请参考以下文章