您的位置:首页 > 其它

N皇后问题 递归回溯

2018-01-12 13:46 218 查看
N皇后问题为在N*N的棋盘中放入N个皇后使其不会相互攻击(当两个皇后位于同一行或同一列或同一对角线上时会相互攻击)解决方法是递归回溯,依次对每行选取一个皇后,对于该行的每个选择都有其后续的选择,所以对该行的所有可行的列递归求解之后的行的情况,再回溯。

#include <cstdio>
#include <iostream>
#include <cstring>
#include <algorithm>
using namespace std;
const int maxn = 105;
int vis[5][maxn];
int C[maxn];   //C[i]为第i行的皇后所在的列
int tot, N;    //tot 最终解的个数
void Search(int cur){ //逐行选择,则只需避免两个位于同一列或同一对角线
if(cur==N){ //满足该条件则说明找到了一组解
tot++;
printf("Case #%d\n",tot);
for(int i = 0; i < N; i++){
for(int j = 0; j < N; j++){
if(C[i]==j)
printf("O");
else
printf("X");
}
printf("\n");
}
printf("\n");
}
else
for(int i = 0; i < N; i++){
if(!vis[0][i]&&!vis[1][cur+i]&&!vis[2][cur-i+N]){
C[cur]=i;
vis[0][i]=vis[1][cur+i]=vis[2][cur-i+N]=1;
Search(cur+1);
vis[0][i]=vis[1][cur+i]=vis[2][cur-i+N]=0;
//vis[0][i]=1为标记第i列有皇后存在
//vis[1][cur+i]=1为标记次对角线有皇后存在
//  在同一次对角线上的元素满足行数和列数的和相等
//vis[2][cur-i+N]=1为标记主对角线有皇后存在
//  在同一主对角线上的元素满足行数和列数的差相等 但要避免差为负值
//最后回溯 将标记取消
}
}
}
int main(){
while(~scanf("%d",&N)){
if(N<1||(N>1&&N<4)){
printf("No solution.\n");
continue;
}//N皇后问题有解当且仅当N=1或N>=4
tot=0;
memset(vis,0,sizeof(vis));
memset(C,0,sizeof(C));
Search(0);
printf("The total number of solutions is %d\n",tot);
}

return 0;
}
内容来自用户分享和网络整理,不保证内容的准确性,如有侵权内容,可联系管理员处理 点击这里给我发消息
标签:  递归 回溯