回溯法:应用举例--八皇后问题

回溯法:回溯法(探索与回溯法)是一种选优搜索法,又称为试探法,按选优条件向前搜索,以达到目标。但当探索到某一步时,发现原先选择并不优或达不到目标,就退回一步重新选择,即返回上一级递归调用,这种走不通就退回再走的技术为回溯法。正是这个原因,递归枚举算法常被称为回溯法,应用十分普遍。八皇后问题是回溯法应用的一个典型问题。

问题描述:玩过国际象棋的人都知道,皇后可以在横、竖、斜线上不限步数地吃掉其他棋子。现如今给你一个8*8的棋盘,要求你放入8个皇后,使每个皇后不能直接攻击到其她皇后,输出有多少种方案。在这里,我们将问题泛化,输入任意的n,输出n*n的棋盘中放入n个皇后的方案数。

分析:用c[x]表示放置在第x行的皇后的列数,将问题转化为全排列生成问题,暴力枚举找出答案。在这里,我们在判断一个皇后放在某个位置是否合法时,可以直接循环扫描已经放好的皇后判断与之是否冲突(代码1),也可以设一个二维数组做标记来判断(代码2)。

注:如果在回溯法中使用了辅助的全局变量,一定要及时把他们恢复原状。特别的,如果函数有多个出口,则需要在每个出口初恢复被修改的值。(刘汝佳算法竞赛入门经典中原话,想了想确实如此,这个点是最容易忘记还不容易检查出来的地方,故拿出来提醒一下)

代码1:

#include<cstdio>
#include<iostream>
#include<algorithm>
#include<cstring>
using namespace std;
const int maxn=105;
int tot,n;
int c[maxn];

void search_queen(int cur){
    if(cur==n) tot++; //d递归边界。只要走到这所有皇后必然不冲突
    else {
        for(int i=0;i<n;i++){
            int ok=1;
            c[cur]=i; //尝试把第cur行的杭后放到第i列
            for(int j=0;j<cur;j++){ //检查是否与之前放好的皇后冲突,横向上肯定不会冲突,因此只需要检查纵向,斜向
                if(c[cur]==c[j]||cur-c[cur]==j-c[j]||cur+c[cur]==j+c[j]){ 
                    ok=0;
                    break;
                }
            }
            if(ok) search_queen(cur+1); //如果此位置合法,继续递归寻找下一个皇后的位置
        }
    }
}

int main () {
    //freopen("in.txt", "r", stdin);
    cin>>n;
    search_queen(0);
    cout<<tot<<endl;
    return 0;
}

代码二:

#include<cstdio>
#include<iostream>
#include<algorithm>
#include<cstring>
using namespace std;
const int maxn=105;
int tot,n;
int c[maxn],vis[2][maxn];

void search_queen(int cur){
    if(cur==n) tot++;
    else {
        for(int i=0;i<n;i++){
            if(!vis[0][i]&&!vis[1][i+cur]&&!vis[2][cur-i+n]) { //二维数组直接判断,顺序为:列,副对角线,主对角线
                c[cur]=i;
                vis[0][i]=vis[1][cur+i]=vis[2][cur-i+n]=1;//标记
                search_queen(cur+1);
                vis[0][i]=vis[1][cur+i]=vis[2][cur-i+n]=0;//递归完成后一定要修改回来
            }
        }
    }
}

int main () {
    //freopen("in.txt", "r", stdin);
    cin>>n;
    search_queen(0);
    cout<<tot<<endl;
    return 0;
}

    原文作者:回溯法
    原文地址: https://blog.csdn.net/sunshine_victory/article/details/76906369
    本文转自网络文章,转载此文章仅为分享知识,如有侵权,请联系博主进行删除。
点赞