八皇后问题——C++

八皇后问题是用回溯法和DFS解决的经典问题,难点在于如何判断所放的皇后是否在同一行列或是对角线上,本文就简单的介绍一下自己的思路,也算是对之前所学的知识做一个简单的总结;

  1. 维护皇后放入位置的数组。第一个数组是一个皇后所放置的行列位置,用一位数组即可表示,下标是行数,下标所对应的值是列数,每次递归就是往第index行的某一列放入皇后。用一维数组就不需要判断是否在同一行。
  2. 维护所放入列的数组。上面的一维数组只保证了是否同一行的条件,所以我们需要用一个一维数组记录哪一列放有元素,每次递归的过程中,就判断该列之前是否有放入过皇后。这样,通过维护两个数组就解决了两个皇后是否在同一行列的问题。
  3. 用abs(j,index)==abs(mat[j],i)来判断是否在同一对角线。首先我们要明白,如果在同一对角线,那么两个皇后的各自行列相减的值是一样的。用abs()函数返回差的绝对值。

下面就是用代码实现:

#include<cstdio>
const int maxn = 8;
int mat[maxn+1]={0};// 记录插入棋子的位置
int vis[maxn+1] = {0};// 判断插入的列是否重复
int cnt=0;
int abs(int a,int b){
    return a>b?a-b:b-a;
}
void bfs(int index){// 记录的是mat的下标
    if(index == maxn+1){// 说明全部插入结束,得到正确的结果
        cnt++;
        return;
    }
    for(int i=1;i<maxn+1;i++){// 开始往第index行第i列插入
        if(!vis[i]){// i列之前没被插入过棋子
            int flag = 1;// 判断这个位置是否可以插入的标记
            for(int j=1;j<index;j++){
                if(abs(j,index)==abs(mat[j],i)){//判断是否在同一对角线
                    flag = 0;break;
                }
            }
            if(flag){// 如果可以,则进入下一步的递归
                mat[index] = i;
                vis[i] = 1;
                bfs(index+1);
                vis[i] = 0;
            }
        }
    }
    return;
}
int main(){
    bfs(1);
    printf("%d",cnt);
    return 0;
}

 

  • 1
    点赞
  • 2
    收藏
    觉得还不错? 一键收藏
  • 1
    评论
评论 1
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值