回溯算法解决n皇后问题

问题描述

题目

输入一个正整数N,请写一个程序,输出N皇后问题的全部摆法。

输入

输入皇后的个数n(n<=13)

样例

4

输出

输出长度为n的正整数。

输出结果里的每一行都代表一种摆法。

行里的第i个数字如果是n,就代表第i行的皇后应该放在第n列。

皇后的行、列编号都是从1开始算

样例

2413
3142

思路

我们优先考虑在每一列放皇后,所有皇后不能有出现在同一行的,所以我们用used数组存储每个皇后所在的行,放过的行不能再放。最后再写一个check函数对皇后对角线上的位置进行检查,如果对角线上也没有皇后,则说明目前这种摆法是可以的,迭代开始摆下一行,摆完所有行就是一种正确的摆法。最后利用回溯输出所有可能的摆法。

代码实现

我们先来看用以回溯的函数batrack。

void batrack(vector<int>& path,vector<int>&used,int n){//path用来存储本次放置皇后的位置,used用来存储这一行是否放置过皇后,n是棋盘大小
    if(path.size()==n){//如果放置的皇后数量等于棋盘长度,说明找到了一种解法,输出这种解法
        for(int i=0;i<n;i++){
            cout<<path[i];
        }
        cout<<endl;
    }
    for(int j=0;j<n;j++){//遍历每一行,放置皇后
        if(used[j]==1)//如果这一行已经放置过皇后了,则跳过这一行
            continue;
        path.push_back(j+1);//否则把皇后放在这一行
        if(!check(path)){//检查皇后对角线上是否有皇后存在
            path.pop_back();//如果有,则不能放在这一行
            continue;
        }
        used[j]=1;//否则可以放在这一行,在used数组中把这一行标记为已放置皇后
        batrack(path,used,n);//递归,讨论下一列皇后放置的位置
        used[j]=0;//回溯,把皇后拿走,考虑下一种摆法
        path.pop_back();//拿走皇后
    }
}

接下来看check函数的实现

bool check(vector<int>& path){
    int len=path.size();
    for(int i=len-2;i>=0;i--){//从棋盘最后摆的那列的前一列开始检查
        if(path[len-1]-path[i]==len-1-i||path[i]-path[len-1]==len-1-i){
//如果行差的绝对值等于列差,则说明两个皇后在对角线上,不可以这样摆,返回false
            return false;
        }
    }
//没有找到,说明可以这样摆,返回true
    return true;
}

 再在主函数中实现输入输出的功能即可。

int main(){
    int n;
    cin>>n;
    vector<int> path;
    vector<int> used(n,0);
    batrack(path,used,n);
}

评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值