10+行代码解决八皇后问题

//C语言 递归+回溯 八皇后问题
//文末附10+行代码解决八皇后问题(全排列函数)
/*
chess[8][8]:国际象棋棋盘 (0表示不放皇后,1表示放皇后)
row[8]:棋盘中每一行是否满足要求(规定row[i]<=0为满足要求)
col[8]:棋盘中每一列是否满足要求(规定col[i]<=0为满足要求)
left[15]: 棋盘中每一条左斜线是否满足要求(规定left[15] <=0为满足要求,且左上为起始)
right[15]:棋盘中每一条右斜线是否满足要求(规定right[15]<=0为满足要求,且右上为起始)
/
//算法详解:1.right[i-j+7] 表示在8
8的棋盘中,第i行,第j列所对应的右斜线。(自己画一画就了然)
#include<stdio.h>
int chess[8][8]={0},row[8]={0},col[8]={0},left[15]={0},right[15]={0};
int ans=0;
int isRight(){ //判断是否符合要求
int i,j,flag=0;
for(i=0;i<8;i++){
if(row[i]>1||col[i]>1)return 0;
for(j=0;j<8;j++){
if(left[i+j]>1||right[i-j+7]>1){
return 0;
}
}
}
return 1;
}
void dfs(int n){ //传入的n作棋盘的列
//递归出口,当n8表明当前已经试探到棋盘的最后一列
if(n
8){
if(isRight()){
ans++;
printf(“第%d种解法:\n”,ans);
for(int i=0;i<8;i++){
for(int j=0;j<8;j++){
printf("%d “,chess[i][j]);
}
printf(”\n");
}
}
return;
}
else{
for(int i=0;i<8;i++){//i作行
chess[i][n]=1;//试探
row[i]++;col[n]++;left[i+n]++;right[i-n+7]++;//看上面解释
if(isRight())//满足要求则进行递归,否则回溯到前一步
dfs(n+1);
chess[i][n]=0;//回溯
row[i]–;col[n]–;left[i+n]–;right[i-n+7]–;
}

}

}
int main(){
dfs(0);
printf(“共有%d种解法\n”,ans);
return 0;
}
ps:如果只是想求出有多少种解法,大可以直接用一个一维数组代替chess。本程序只为算法小白理解而生,大佬若有更好算法,可请指教(事实上确实还可以优化一下)
以下利用C++全排列函数轻松解决:
#include
#include
#include
using namespace std;
int main(){
int chess[8]={1,2,3,4,5,6,7,8},ans=0,i,j;
do{
int flag=1;
ans++;
for(i=0;i<8&&flag;i++)
for(j=i+1;j<8&&flag;j++)
if(abs(i-j)==abs(chess[i]-chess[j])){
flag=0;ans–;
}
}while(next_permutation(chess,chess+8));
cout<<ans<<endl;
return 0;
}

猜你喜欢

转载自blog.csdn.net/qq_41308254/article/details/84848559