51. N 皇后

93 篇文章 0 订阅
34 篇文章 0 订阅
本文介绍了一个编程问题,即如何在n×n的棋盘上放置n个皇后,使得它们不会互相攻击。使用了回溯算法并提供了C++代码示例,展示了如何通过递归找到所有可能的解决方案。
摘要由CSDN通过智能技术生成

按照国际象棋的规则,皇后可以攻击与之处在同一行或同一列或同一斜线上的棋子。 n 皇后问题 研究的是如何将 n 个皇后放置在 n×n 的棋盘上,并且使皇后彼此之间不能相互攻击。

给你一个整数 n ,返回所有不同的 n 皇后问题 的解决方案。

每一种解法包含一个不同的 n 皇后问题 的棋子放置方案,该方案中 ‘Q’ 和 ‘.’ 分别代表了皇后和空位。

示例 1:
在这里插入图片描述

输入:n = 4
输出:[[“.Q…”,“…Q”,“Q…”,“…Q.”],[“…Q.”,“Q…”,“…Q”,“.Q…”]]

解释:如上图所示,4 皇后问题存在两个不同的解法。

示例 2:
输入:n = 1
输出:[[“Q”]]

提示:

  • 1 <= n <= 9

回溯法

#include<iostream>
#include<string>
#include<vector>
using namespace std;

bool judgeValid(vector<string> board, int curRow, int curCol, int queenNum) {
	vector<vector<string>> res;
	//由于每次均row+1,不存在同行存在的可能
	//判断是否同列
	for (int r = 0; r < queenNum; r++){
		if (board[r][curCol] == 'Q') {
			return false;
		}
	}
	//判断是否同在左斜线(由于是按行从上到下,依次放置,因此只用判断左上角,不用判断右下角)
	for (int i = curRow - 1, j = curCol - 1; i >= 0 && j >= 0; i--, j--) {
		if (board[i][j] == 'Q') {
			return false;
		}
	}
	//判断是否同在右斜线(由于是按行从上到下,依次放置,因此只用判断右上角,不用判断左下角)
	for (int i = curRow - 1, j = curCol + 1; i >= 0 && j < queenNum; i--, j++) {
		if (board[i][j] == 'Q') {
			return false;
		}
	}

	return true;
}

void backtrack(vector<string> &board, vector<vector<string>> &res, int row, int queenNum) {
	if (row == queenNum){
		res.push_back(board);
		return;
	}

	for (int col = 0; col < queenNum; col++){
		if (judgeValid(board,row,col,queenNum)){
			board[row][col] = 'Q';
			backtrack(board, res, row + 1, queenNum);//穷尽在当前情况下,下一行怎样放置
			board[row][col] = '.';//回溯(寻找第一行放置不同列情况下有多少种可能)
		}
	}
}

vector<vector<string>> solveNQueens(int queenNum) {
	//生成棋盘
	vector<vector<string>> res;//存储最终结果
	vector<string> board(queenNum, string(queenNum, '.'));//生成棋盘
	backtrack(board, res, 0, queenNum);//回溯法求解所有结果

	return res;
}

int main() {

	int queenNum = 5;
	vector<vector<std::string>> res = solveNQueens(queenNum);
	for (const auto& row : res) {
		for (const auto& col : row) {
			std::cout << col << " ";
		}
		std::cout << std::endl; // 换行
	}
	system("pause");
	return 0;
}
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包

打赏作者

colorful_stars

您是我见过全宇宙最可爱的人!

¥1 ¥2 ¥4 ¥6 ¥10 ¥20
扫码支付:¥1
获取中
扫码支付

您的余额不足,请更换扫码支付或充值

打赏作者

实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

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

余额充值