八皇后问题(递归实现)
八皇后问题是回溯法的典型例题,就同一问题有许多不同种解法,这里只通过递归解决八皇后问题
所谓八皇后问题是由高斯先生提出的一个关于国际象棋的数学问题,其要求在8x8的棋盘上放置8个皇后,每个皇后之间不能互相攻击到对方(皇后的攻击方式是米字型),高斯先生穷其一生发现了76钟解法,在没有计算机的年代已经非常了不起了。
大体思路:
1.建立一个8x8的二维数组来当做棋盘
2.通过循环一列一列来摆放皇后
3.每放完8列输出一次
面临的问题:
1.如何确定皇后所在位置是否安全
2.从哪递归
解决问题:
1.按照皇后的攻击方式,分别判断皇后所在列,斜角是否存在别的皇后
2.就从哪开始递归而言,每个写代码的人都应该有自己的想法,只提供一个参考思路,每摆放一行皇后,便递归
如果对递归不了解可以参考一下
https://blog.csdn.net/duan19920101/article/details/51252577?utm_source=blogxgwz7
#include <iostream>
using namespace std;
int count = 0;
void EightQueen(int row,int rank,int (*chess)[8]);
int NotDanger(int row,int rank,int (*chess)[8]);
int main()
{
int chess[8][8];
memset(chess,0,sizeof(chess));
EightQueen(0,8,chess);
cout << "There are " << count << " solutions.\n";
return 0;
}
void EightQueen(int row,int rank,int (*chess)[8])
{
int temp_chess[8][8]; //临时棋盘存放解法
for(int i=0; i<8; i++){
for(int j=0; j<8; j++){
temp_chess[i][j] = chess[i][j];
}
}
if(8 == row)
{
cout << "the " << count + 1 << ':' << endl;
for(int i=0; i<8; i++){
for(int j=0; j<8; j++){
cout << *(*(temp_chess+i)+j) << ' ';
}
cout << endl;
}
cout << endl;
count++;
}
else
{
for(int i=0; i<rank; i++){
if(NotDanger(row,i,chess))
{
for(int j=0; j<8; j++){
*(*(temp_chess + row) + j) = 0;
}
*(*(temp_chess + row) + i) = 1;
EightQueen(row + 1,rank,temp_chess);
}
}
}
}
int NotDanger(int row,int rank,int (*chess)[8])
{
int flag = 1;
int i,j;
//判断列
for(i=0; i<8; i++){
if(*(*(chess+i)+rank) != 0)
{
flag = 0;
break;
}
}
//判断左上
for(i=row,j=rank; i>=0 && j>=0; i--,j--){
if(*(*(chess+i)+j) != 0)
{
flag = 0;
break;
}
}
//判断右下
for(i=row,j=rank; i<8 && j<8; i++,j++){
if(*(*(chess+i)+j) != 0)
{
flag = 0;
break;
}
}
//判断右上
for(i=row,j=rank; i>=0 && j<8; i--,j++){
if(*(*(chess+i)+j) != 0)
{
flag = 0;
break;
}
}
//判断左下
for(i=row,j=rank; i<8 && j>=0; i++,j--){
if(*(*(chess+i)+j) != 0)
{
flag = 0;
break;
}
}
return flag;
}