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

本文深入探讨了使用C语言解决经典的八皇后问题,通过递归与回溯算法实现棋盘上的皇后放置,确保每行、每列及对角线没有皇后冲突。文章提供了详细的代码解释,包括如何检查行、列和对角线的冲突状态,以及如何利用递归进行搜索和回溯。

摘要生成于 C知道 ,由 DeepSeek-R1 满血版支持, 前往体验 >

//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;
}

评论 2
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值