编写一个递归算法,求解n皇后问题:在n×n的方格棋盘上放置n个皇后,要求每个皇后不同行、不同列、不同左右斜对角线。
算法思想:
- 第i个皇后放在第i行,col[i]表示第i(1≤i≤n)个皇后的列号。即第i个皇后的坐标位置是(i,col[i])。
- 对于第k个皇后,测试(k, j)(1≤j≤n)是否与1~k-1个皇后有冲突。对于第i个皇后,位置是(i,col[i]),是否与(k,j)有冲突呢?显然是不同行的。若同列有
col[i]==j
,若同一对角线有|j-col[i]|==|k-i|
。 - queen(k,n)是在1~k-1行上已经放好了k-1个皇后,在第k行找到所有合适列位置j,放一个皇后,再递归执行queen(k+1,n)。
#include<stdio.h>
#include<stdlib.h>
#define N 20 //最多支持20个皇后
int col[N]; //col[i]存放第i个皇后的列号
int count=0; //统计解的个数
bool place(int k, int j) //测试(k,j)位置能否摆放皇后
{ int i=1;
while(i<k)
{ if(j==col[i] || abs(j-col[i])==abs(k-i) )
return false; //相同列或相同对角线
i++;
}
return true;
}
void queen(int k, int n) //放置1~k的皇后
{
if(k>n) //n个皇后放置完毕,输出解
{ count++;
printf(" 第%d个解:",count);
for(int i=1;i<=n;i++)
printf("(%d,%d) ", i, col[i]);
printf("\n");
}
else
for(int j=1;j<=n;j++) //在第k行上穷举每一个列号j
if(place(k,j)) //在第k行找到一个合适位置(k,j)
{ col[k]=j;
queen(k+1,n);
}
}
int main()
{ int n; //n存放皇后的个数
printf("皇后的个数n=");
scanf("%d",&n);
if(n>20)
printf("n太大不能求解\n");
else
{
printf("%d皇后问题求解如下:\n", n);
queen(1,n);
}
}