**
递归算法——n皇后
**
n皇后问题:
输入整数n,要求n个国际象棋的皇后,摆在n*n的棋盘上,互相不能攻击,输出全部方案。
输入:
输入一个正整数N。
输出:
程序输出N皇后问题的全部摆法。
行里的第i个数字如果是n,就代表第i行的皇后应该放在第n列。
皇后的行、列编号都是从1开始算起。
输入样例:
4
输出样例:
2 4 1 3
3 1 4 2
解题思路:
国际象棋皇后的走法是横、直、斜均可走,但每次只能走一格。
问题要求把n个皇后放在一个n*n的棋盘上,使得任何两个皇后都不能相互攻击,即它们不能同行,不能同列,也不能位于同一条对角线上。对于n= 1,问题的解很简单,而且很容易看出对于n=2和n=3来说,这个问题是无解的。
所以我们以4皇后问题为例,用递归法对它求解。
因为每个皇后都必须分别占据一行,我们需要做的不过是为棋盘上的每个皇后分配一列。
我们从空棋盘开始,然后把皇后1放到它所在行的第一个可能位置上,也就是第一行第一列。对于皇后2,在经过第一列和第二列的失败尝试之后,我们把它放在第一个可能的位置,就是格子(2, 3),位于第二行第三列的格子。这被证明是一个死胡同,因为皇后3将没有位置可放。所以,该算法进行递归,把皇后2放在下一个可能位置(2, 4)上。这样皇后3就可以放在(3, 2),这被证明是另一个死胡同。该算法然后就递归到底,把皇后1移到(1,2), 接着皇后2到(2,4), 皇后3到(3,1), 而皇后4到(4, 3), 这就是该问题的一个解。
代码:
#include<stdio.h>
#include<math.h>
int N;//皇后的数量,以及棋盘的大小 N*N
int queenPos[100];//皇后在棋盘中每一行的列号
void NQueen(int k)//表示行位置
{
int i;//表示列位置
if(k==N)//当k=n时,就是要摆放最后一行的皇后
{
for(i=0;i<N;i++)
{
printf("%d",queenPos[i]+1); //C语言从0开始计数,所有输出需要加1
}
}
else
{
for(i=0;i<N;i++)//遍历每一个皇后
{
int j;
for(j=0;j<k;j++)
{
if(queenPos[j]==i||abs(queenPos[j] - i)==abs(k-j))//queenPos[j]相当于上一层的queenPos[k]的值
{
break;
}
}
if(j==k)
{
queenPos[k]=i;
NQueen(k+1);
}
}
}
return ;
}
int main()
{
scanf("%d",&N);//输入皇后数量
NQueen(0);
return 0;
}
运行结果: