我一直在尝试使用回溯来解决 N 皇后问题。我在网上找到的大多数方法都涉及向量,这让我很难像互联网上的一些小程序那样将解决方案可视化。
我想出的解决方案给了我很多问题(我感觉这与使用的动态 2D 数组的索引有关)并且我无法使用 Dev-C++ 调试器解决它。任何帮助和/或建设性的批评受到高度赞赏。提前谢谢了。
这是我想出的解决方案:
#include<iostream>
#include<string.h>
#include<conio.h>
using namespace std;
void display(char** b, int len);
void initialize(char** &b, int k);
void consider1strow(char ** b, int len);
void markunsafe(char** board, int rowno, int colno);
void marksafe(char** board, int rowno, int colno);
void considerrow(char** board, int rowno);
void backtrack(char** board, int rowno);
bool checksafety(char** board, int rowno, int colno);
void place(char** board, int rowno, int colno);
void solve(char** board, int len);
int state[20] = { 0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0 };
int len;
void display(char** board, int len)
{
int i, j;
cout << endl << "The current state of the board:" << endl;
for (i = 0; i < len; i++)
{
for (j = 0; j < len; j++)
{
cout << board[i][j];
}
cout << endl;
}
}
void initialize(char** &b, int k)
{
int i, j;
//create dynamic board
b = new char*[k];
for (i = 0; i < k; i++)
{
b[i] = new char[k];
}
//initialize array
for (i = 0; i < k; i++)
{
for (j = 0; j < k; j++)
{
b[i][j] = '-';
}
}
}
void consider1strow(char ** board, int len)
{
int col;
cout << "Enter the column to try for the first row!";
cin >> col;
board[0][col - 1] = 'Q';
state[0] = col - 1;
markunsafe(board, 0, col - 1);
display(board, len);
}
void markunsafe(char** board, int rowno, int colno)
{
int i, j;
//mark row as unsafe
for (i = 0; i < len; i++)
{
board[rowno][i] = 'x';
}
//mark column as unsafe
for (i = 0; i < len; i++)
{
board[i][colno] = 'x';
}
//mark unsafe diagonals
for (i = 0; i < len; i++)
{
for (j = 0; j < len; j++)
{
if ((rowno + colno) == (i + j))
{
board[i][j] = 'x'; //check if index gives a problem of +/- 1
}
if ((rowno - colno) == (i - j))
{
board[i][j] = 'x'; //check if index gives a problem of +/- 1
}
}
}
board[rowno][colno] = 'Q';
}
void marksafe(char** board, int rowno, int colno)
{
int i, j;
//mark row as safe
for (i = 0; i < len; i++)
{
board[rowno][i] = '-';
}
//mark column as unsafe
for (i = 0; i < len; i++)
{
board[i][colno] = '-';
}
//mark unsafe diagonals
for (i = 0; i < len; i++)
{
for (j = 0; j < len; j++)
{
if ((rowno + colno) == (i + j))
{
board[i][j] = '-'; //check if index gives a problem of +/- 1
}
if ((rowno - colno) == (i - j))
{
board[i][j] = '-'; //check if index gives a problem of +/- 1
}
}
}
}
void considerrow(char** board, int rowno)
{
bool safe = 0;
int i;
for (i = 0; i < len; i++)
{
safe = checksafety(board, rowno, i);
if (safe && (i >= state[rowno]))
{
break;
}
}
if (safe && (i >= state[rowno]))
{
place(board, rowno, i);
}
else if (!safe)
{
backtrack(board, rowno);
}
}
void backtrack(char** board, int rowno)
{
marksafe(board, rowno - 2, state[rowno - 2]);
considerrow(board, rowno);
}
bool checksafety(char** board, int rowno, int colno)
{
if (rowno == 0)
{
return 1;
}
else if (board[rowno][colno] == 'x')
{
return 0;
}
else if (board[rowno][colno] == '-')
{
return 1;
}
}
void place(char** board, int rowno, int colno)
{
board[rowno][colno] = 'Q';
state[rowno] = colno;
markunsafe(board, rowno, colno);
}
void solve(char** board, int len)
{
int i = 0;
if (i == len)
{
display(board, len);
}
else
{
consider1strow(board, len);
for (i = 1; i < len; i++)
{
considerrow(board, i);
}
}
}
int main()
{
char** board;
cout << "Enter the size of the board!";
cin >> len;
initialize(board, len);
solve(board, len);
getch();
}