N皇后问题可以看作八皇后问题的延申,在八皇后问题中我们可以使用BF八重循环解决,而在N皇后问题中,明显不能够再使用循环解决,这是一种递归代替循环的算法。
N皇后问题
输入整数n,要求n个国际象棋的皇后,摆放在n*n的棋盘上,互相不能攻击。输出全部方案。输出结果里的每一行都代表一种摆法。行里的第i个是数字如果是n,就代表第I行的皇后应该放在第n列。皇后的行、列编号都是从1开始算。
样例输入:
4
样例输出:
2 4 1 3
3 1 4 2
#include<stdio.h>
#include<iostream>
#include<cmath>
using namespace std;
int N;
int queenpos[100];//用来存放算好的皇后位置,最左上角是(0,0)
void Nqueen(int k){//在0~k-1行皇后已经摆好的情况下,摆放第k行及其后的皇后
int i,j;
if(k==N){//n个皇后已经摆好,输出即可
for(i=0;i<N;i++){
printf("%d ",queenpos[i]+1);
}
printf("\n");
return;
}
for(i=0;i<N;i++){//逐尝试第k个皇后可能所在的列位置
for(j=0;j<k;j++){//和已经摆放好的k个皇后位置比较
if(queenpos[j]==i||abs(queenpos[j]-i)==abs(k-j)){
break;//对角线或所在行列有冲突,直接跳出里循环,i++
}
}
if(j==k){//如果上面的内循环遍历一遍,此时j==k,即所选的i位置不与之前的k-1个皇后冲突
queenpos[k]=i;//将第k个皇后摆放在位置i即可
Nqueen(k+1);
}
}
}
int main(){
scanf("%d",&N);
Nqueen(0);//从第0行开始摆放皇后
getchar();
getchar();
return 0;
}
无论对于左上到右下的对角线或者是从左上到右下的对角线,两个端点都满足棋盘位置的行和列之差的绝对值相等。