N皇后问题(回溯法):看不懂你打我系列-LeetCode51

本文详细讲解了如何使用回溯算法解决经典的N皇后问题,包括初始化attack数组、queen数组,设计dx和dy遍历攻击范围,并通过put_queen函数放置皇后并更新攻击范围。通过backtrack函数实现递归,展示如何开发和测试solveNQueens函数来找到所有可能的皇后布局。
摘要由CSDN通过智能技术生成

问题描述

题目链接:

n皇后问题

问题解决

初始化attack数组和queen数组

attack数组用于更新攻击范围,而queen用于更新皇后摆放位置。

设计dx、dy用于遍历八个方向的攻击范围(注意由于是扩散遍历所以应单独取值)

写出put_queen函数(实现在位置(x,y)放置皇后,同时对attack数组更新)

在写代码前需要清楚:vector容器的基本运用->vector容器创建的数组可以直接通过如:vector< int > a;vector< int > b;

a=b;直接等同将b中的数据备份到a。

//自定义函数put_queen,实现在(x,y)放置皇后,对attack数组的更新
//x、y表示放置皇后的坐标,二维数组attack表示棋盘是否可放置皇后
void put_queen(int x,int y,vector<vector<int>> &attack){
    //方向数组,方便后面对8个方向进行标记
    static const int dx[] ={-1,1,0,0,-1,-1,1,1};
    static const int dy[] = {0,0,-1,1,-1,1,-1,1};
    //通过两层循环,将皇后可能攻击到底的位置进行标记
    for(int i = 1;i<attack.size();i++){//从皇后位置向1到n-1距离延伸
        for(int j = 0;j<8;j++){//遍历八个方向
            int nx = x+i*dx[j];//生成新位置行
            int ny = y+i*dy[j];//生成新位置列
            if(nx>=0&&nx<attack.size()&&ny>=0&&ny<attack.size()){
                attack[nx][ny] = 1;//将新位置标记为1
            }
        }
    }

写出回溯算法的递归函数backtrack

//k表示当前处理的行
//n表示N皇后问题
//queen存储皇后的位置
//attack标记皇后的攻击位置
//solve存储N皇后的全部解法
void backtrack(int k,int n,vector<string>&queen,vector<vector<int>>&attack,vector<vector<string>>&solve){
    if(k==n){//找到一组解
        solve.push_back(queen);//将结果queen存储至solve
        return;//返回
    }
    //遍历0至n-1列,在循环中,回溯试探皇后可知放置的位置
    for(int i=0;i<n;i++){
        if(attack[k][i]==0){//判断当前第k行第i列是否可以放置皇后
            vector<vector<int>>tmp = attack;//备份attack数组
            queen[k][i]='Q';//标记该位置为'Q'
            put_queen(k,i,attack);//更新attack数组
            backtrack(k+1,n,queen,attack,solve);//递归试探k+1行的皇后放置
            attack = tmp;//恢复attack数组
            queen[k][i]='.';//恢复queen数组
        }
    }
}

solveNQueens函数开发

vector<vector<string>>solveNQueens(int n){
    vector<vector<string>>solve;//存储最后的结果
    vector<vector<int>>attack(n,vector<int>(n,0));//标记皇后的攻击位置
    vector<string>queen(n,string(n,'.'));//保存皇后的位置
    
    backtrack(0,n,queen,attack,solve);//调用backtrack求解N皇后问题
    return solve;
}

测试main函数

int main(){
    vector<vector<string>>result;
    result = solveNQueens(8);
    printf("8皇后共有%d种解法:\n\n",result.size());
    for(int i = 0;i<result.size();i++){
        printf("解法%d:\n",i+1);
        for(int j = 0;j<result[i].size();j++){
            printf("%s\n",result[i][j].c_str());
        }
        printf("\n");
    }
	return 0;
}
评论 1
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值