八皇后问题是一个以国际象棋为背景的问题:如何能够在8×8的国际象棋棋盘上放置八个皇后,使得任何一个皇后都无法直接吃掉其他的皇后?为了达到此目的,任两个皇后都不能处于同一条横行、纵行或斜线上。八皇后问题可以推广为更一般的n皇后摆放问题:这时棋盘的大小变为n×n,而皇后个数也变成n。当且仅当n = 1或n ≥ 4时问题有解。
‘’
回溯法
#include<stdio.h>
#include<stdlib.h>
#include<string.h>
int n = 4;
char a[4][4];
void Pri()
{
int i,j;
for(i = 0;i < n;i++)
{
for(j = 0;j < n;j++)
printf("%c ",a[i][j]);
printf("\n");
}
}
int valid(int row,int col)
{
//判断当前列有没有皇后,因为是一行一行往下走的
//我们只需要检查走过的行数即可,通俗一点就是
//判断当前坐标位置的上面有没有皇后
int i,j;
for(i = 0;i < row;i++)
{
if(a[i][col] == 'Q')
return 0;
}
//判断当前坐标的右上角有没有皇后
for(i = row -1,j = col + 1;i >= 0&& j < n;i--,j++)
{
if(a[i][j] == 'Q')
return 0;
}
//判断当前坐标的左上角有没有皇后
for(i = row - 1,j = col -1;i >= 0&& j >= 0;i--,j--)
{
if(a[i][j] == 'Q')
return 0;
}
return 1;
}
void solve(int row)
{
int col;
if(row == n)
{
Pri();
printf("\n\n");
return ;
}
for(col = 0;col < n;col++)
{
if(valid(row,(int)col))
{
a[row][col] = 'Q';
solve(row+1);
a[row][col]='.';
}
}
}
int main()
{
int i,j;
for(i = 0;i < n;i++)
for(j = 0;j < n;j++)
a[i][j] = '.';
solve(0);
return 0;
}
二叉树法–先序遍历
void solveNQueens(int n) {
char[][] chess = new char[n][n];
for (int i = 0; i < n; i++)
for (int j = 0; j < n; j++)
chess[i][j] = '.';
solve(chess, 0);
}
void solve(char[][] chess, int row) {
if (row == chess.length) {
//自己写的一个公共方法,打印二维数组的,
// 主要用于测试数据用的
Util.printTwoCharArrays(chess);
System.out.println();
return;
}
for (int col = 0; col < chess.length; col++) {
if (valid(chess, row, col)) {
char[][] temp = copy(chess);
temp[row][col] = 'Q';
solve(temp, row + 1);
}
}
}
//把二维数组chess中的数据测下copy一份
char[][] copy(char[][] chess) {
char[][] temp = new char[chess.length][chess[0].length];
for (int i = 0; i < chess.length; i++) {
for (int j = 0; j < chess[0].length; j++) {
temp[i][j] = chess[i][j];
}
}
return temp;
}
//row表示第几行,col表示第几列
boolean valid(char[][] chess, int row, int col) {
//判断当前列有没有皇后,因为他是一行一行往下走的,
//我们只需要检查走过的行数即可,通俗一点就是判断当前
//坐标位置的上面有没有皇后
for (int i = 0; i < row; i++) {
if (chess[i][col] == 'Q') {
return false;
}
}
//判断当前坐标的右上角有没有皇后
for (int i = row - 1, j = col + 1; i >= 0 && j < chess.length; i--, j++) {
if (chess[i][j] == 'Q') {
return false;
}
}
//判断当前坐标的左上角有没有皇后
for (int i = row - 1, j = col - 1; i >= 0 && j >= 0; i--, j--) {
if (chess[i][j] == 'Q') {
return false;
}
}
return true;
}
输出结果