在N*N格的棋盘上放置N个皇后,任何两个皇后不放在同一行或同一列或同一斜线上。
需要注意的是,如图中上面两个矩阵中大于0的那些数据,它们表示此处有几个皇后可以攻击到,如果移走一个皇后,那么她的攻击范围内的危险值减一。
#include <stdio.h>
#define QUEEN -1
#define SAFETY 0
#define MOVEDANGER -1
#define DANGER 1
#define PLACEQUEEN -1
#define TAKEQUEEN 0
int chessboard[20][20];
void InitChessboard(int size)
{
int i, j;
for (i = 0; i < size; i++)
{
for (j = 0; j < size; j++)
{
chessboard[i][j] = SAFETY;
}
}
}
void MarkChessboard(int content, int row, int column, int size)
{
int left, right;
if (content == PLACEQUEEN)
{
chessboard[row][column] = PLACEQUEEN;
content = DANGER;
}
else
{
chessboard[row][column] = TAKEQUEEN;
content = MOVEDANGER;
}
for (row++, left = column-1, right = column+1; row < size; row++)
{
chessboard[row][column] += content;
if (left >= 0)
{
chessboard[row][left--] += content;
}
if (right < size)
{
chessboard[row][right++] += content;
}
}
}
bool Backtrack(int queen, int queenNum)
{
int column;
if (queen == queenNum)
{
return true;
}
for (column = 0; column < queenNum; column++)
{
if (chessboard[queen][column] == SAFETY)
{
MarkChessboard(PLACEQUEEN, queen, column, queenNum);
for (int i = 0; i < queenNum; i++)
{
for (int j = 0; j < queenNum; j++)
{
printf(" %d", chessboard[i][j]);
}
printf("\n");
}
printf("\n");
if (Backtrack(queen+1, queenNum))
{
return true;
}
else
{
MarkChessboard(TAKEQUEEN, queen, column, queenNum);
}
}
}
return false;
}
void DrawChessboard(int size, char left[3], char mid[3], char right[3])
{
int i;
printf("%s", left);
for (i = 1; i < size; i++)
{
printf("━");
printf("%s", mid);
}
printf("━");
printf("%s\n", right);
}
void DisplayChessboard(int size)
{
int i, j;
DrawChessboard(size, "┏", "┳", "┓");
for (i = 0; i < size; i++)
{
printf("┃");
for (j = 0; j < size; j++)
{
if (chessboard[i][j] == QUEEN)
{
printf("★┃");
}
else
{
printf(" ┃");
}
}
printf("\n");
if (i != size-1)
{
DrawChessboard(size, "┣", "╋", "┫");
}
else
{
DrawChessboard(size, "┗", "┻", "┛");
}
}
}
int main()
{
int testNum, queenNum;
scanf("%d", &testNum);
while (testNum-- != 0)
{
scanf("%d", &queenNum);
InitChessboard(queenNum);
if (Backtrack(0, queenNum))
{
DisplayChessboard(queenNum);
}
else
{
printf("Infeasible!\n");
}
}
return 0;
}