题目:
八皇后问题
在8*8格的国际象棋上摆放八个皇后,使其不能互相攻击,即任意两个皇后都不能处于同一行、同一列或同一斜线上,问有多少种摆法
递归思路:在第1行安全位置放一个棋子,在第2行安全位置放一个棋子,以此类推,直到八行都放了棋子,第9行时退出递归过程。
C++代码:
//八皇后问题
//在8*8格的国际象棋上摆放八个皇后,使其不能互相攻击,即任意两个皇后都不能处于同一行、同一列或同一斜线上,问有多少种摆法
//思路:在第1行安全位置放一个棋子,在第2行安全位置放一个棋子,以此类推,直到八行都放了棋子,第9行时退出递归过程
#include<iostream>
using namespace std;
#define NUM 8
int Count = 0; //记录摆法个数
int notDanger(int r, int l, int chess[NUM][NUM]) //判断第r+1行、第l+1列的位置是不是安全位置
{
int k = 0, i = 0, j = 0;
int flag = 0;
//判断列方向
for (k = 0; k < NUM; k++)
{
if (chess[k][l] == 1)
{
flag = 1;
break;
}
}
//判断左上方
for (i = r - 1, j = l - 1; i >= 0 && j >= 0; i--, j--)
{
if (chess[i][j] == 1)
{
flag = 1;
break;
}
}
//判断右下方
for (i = r + 1, j = l + 1; i < NUM && j < NUM; i++, j++)
{
if (chess[i][j] == 1)
{
flag = 1;
break;
}
}
//判断左下方
for (i = r + 1, j = l - 1; i < NUM && j >= 0; i++, j--)
{
if (chess[i][j] == 1)
{
flag = 1;
break;
}
}
//判断右上方
for (i = r - 1, j = l + 1; i >= 0 && j < NUM; i--, j++)
{
if (chess[i][j] == 1)
{
flag = 1;
break;
}
}
if (flag == 1)
{
return 0;
}
else return 1;
}
//参数row表示起始行,当前摆放的行编号
//参数line表示总列数
//参数chess[][]表示棋盘
void EightQueen(int row, int line, int chess[NUM][NUM])
{
int i, j;
//注意这里要设置一个chess2,并用chess初始化,这样某一行找不到安全位置,回退到上一行找下一个安全位置时,上一次在上一行摆放皇后的结果不会影响找该行下一个安全位置的过程
int chess2[NUM][NUM];
for (int i = 0; i < NUM; i++)
{
for (int j = 0; j < NUM; j++)
{
chess2[i][j] = chess[i][j];
}
}
if (row == NUM) //起始行是第9行时,摆放结束,打印出结果
{
cout << "第" << Count + 1 << "个排列是:" << endl;
for (i = 0; i < NUM; i++)
{
for (j = 0; j < NUM; j++)
{
cout << chess2[i][j] << " ";
}
cout << endl;
}
Count++;
}
else
{
for (j = 0; j < line; j++)
{
//判断位置是否有危险,如果没有危险继续往下行放,有危险继续在该行寻找安全位置
if (notDanger(row, j, chess2))
{
for (i = 0; i < NUM; i++)//把该行所有位置置为0
{
chess2[row][i] = 0;
}
chess2[row][j] = 1;//仅chess[row][j]位置=1
EightQueen(row + 1, line, chess2);
}
}
}
}
int main()
{
int chess[NUM][NUM], i, j; //chess代表棋盘
for (i = 0; i < NUM; i++) //棋盘初始化为0,放皇后为1
{
for (j = 0; j < NUM; j++)
{
chess[i][j] = 0;
}
}
EightQueen(0, NUM, chess);
system("pause");
return 0;
}