n-皇后问题——DFS

问题描述

第一种方法

  • 每一行放一个皇后
  • 边放皇后边判断是否符合条件
  • 递归到第n行,则说明当前方案符合条件,进行遍历

代码实现

#include <cstring>
#include <iostream>
#include <algorithm>

using namespace std;

const int N = 10;

int n;
char path[N][N];	// 二维棋盘
bool col[N], dg[N * 2], udg[N * 2];	// col表示列、dg表示对角线、udg表示反对角线

void dfs(int u)
{
	if(u == n)	// 当前行数等于n,皇后放置完毕
	{
		for(int i = 0; i < n; i++)
		{
			for(int j = 0; j < n; j++) cout << path[i][j];
			puts("");
		}
		puts("");
		return;
	}
	for(int i = 0; i < n; i++)	// 判断当前行在哪一列放皇后
	{
		if(!col[i] && !dg[u + i] && !udg[u - i + n])	// 满足条件
		{
			path[u][i] = 'Q';
			col[i] = dg[u + i] = udg[u - i + n] = true;	
			dfs(u + 1);
			col[i] = dg[u + i] = udg[u - i + n] = false;	// 回溯
			path[u][i] = '.';
		}
	}
}

int main()
{
	cin >> n;
	for(int i = 0;i < n; i++)	// 初始化
		for(int j = 0; j < n; j++) path[i][j] = '.';
	dfs(0);
	
	return 0;
}

第二种方法

  • 遍历每一个位置,分两种情况
  1. 放皇后
  2. 不放皇后
  • 每次遍历记录当前棋盘上放的皇后的数量
  • 当数量等于n时,当前皇后的放置位置符合条件

代码实现

#include <iostream>
#include <cstring>
#include <algorithm>

using namespace std;

const int N = 10;

int n;
char path[N][N];
bool row[N], col[N], dg[N * 2], udg[N * 2];	// row表示行、col表示列、dg表示对角线、udg表示反对角线

void dfs(int x, int y, int s)	// x表示x轴位置,y表示y轴位置,s表示当前棋盘皇后数量
{
	if(y == n) 	// 当y轴超出棋盘范围,x轴加1,y轴为0
	{
		y = 0;
		x++;
	}
	
	if(x == n)	// 当前位置x轴超出棋盘范围,如果皇后数量为n,当前棋盘满足条件
	{
		if(s == n)
		{
			for(int i = 0; i < n; i++)
			{
				for(int j = 0; j < n; j++) cout << path[i][j];
				puts("");
			}
			puts("");
		}
		return;
	}
	// 不放皇后
	dfs(x, y + 1, s);
	// 放皇后
	if(!row[x] && !col[y] && !dg[x + y] && !udg[x - y + n])
	{
		path[x][y] = 'Q';
		row[x] = col[y] = dg[x + y] = udg[x - y + n] = true;
		dfs(x, y + 1, s + 1);	// y轴加1
		row[x] = col[y] = dg[x + y] = udg[x - y + n] = false;	// 回溯
		path[x][y] = '.';
	}
}

int main()
{
	cin >> n;
    // 初始化
	for(int i = 0;i < n; i++)
		for(int j = 0; j < n; j++) path[i][j] = '.';
	dfs(0, 0, 0);	// 从(0, 0)出发,皇后数量为0
	
	return 0;
}
  • 24
    点赞
  • 9
    收藏
    觉得还不错? 一键收藏
  • 0
    评论
n皇后问题是一个经典的回溯算法问题,它要求在一个n×n的棋盘上放置n个皇后,使得皇后彼此之间不能相互攻击,即不能在同一行、同一列或者同一条斜线上。 在Python中解决n皇后问题的思路如下: 1. 使用一个一维数组board来表示棋盘,数组的每个元素表示每一行皇后所在的列数。例如,board[i]=j表示在第i行的第j列放置了一个皇后。 2. 首先定义一个检查函数check(board, row, col),用于检查当前位置是否可以放置皇后。检查过程中需要判断当前位置是否与之前已放置的皇后发生冲突。 3. 使用深度优先搜索(DFS算法实现,在每一行中从左到右依次尝试放置皇后。如果当前位置通过检查函数的检查,则将当前位置的列数记录在board数组中,并继续递归地处理下一行。 4. 当递归到最后一行时,表示找到了一个解,将board数组中的列数对应的位置输出为皇后的放置情况。 5. 通过调用eightqueen(board, row)函数来启动算法,并传入初始参数,即空的board数组和起始行号。 下面是一个简单的示例代码来解决4皇后问题: ``` def check(board, row, col): for i in range(row): if abs(board[i]-col) == 0 or abs(board[i]-col) == abs(i-row): return False return True def eightqueen(board, row): border = len(board) if row >= border: for i, col in enumerate(board): print('□ ' * col + '■ ' + '□ ' * (len(board) - 1 - col)) print("") col = 0 while col < border: for col in range(border): if check(board, row, col): board[row = col eightqueen(board, row+1) col += 1 board = [0 for i in range(4)] eightqueen(board, 0) ``` 这段代码使用了一个4×4的棋盘,输出了所有合法的皇后放置情况。其中,'□'表示空格,'■'表示皇后。<span class="em">1</span><span class="em">2</span><span class="em">3</span> #### 引用[.reference_title] - *1* *2* [N皇后问题——Python解决(超详细注释)](https://blog.csdn.net/m0_62797649/article/details/127250658)[target="_blank" data-report-click={"spm":"1018.2226.3001.9630","extra":{"utm_source":"vip_chatgpt_common_search_pc_result","utm_medium":"distribute.pc_search_result.none-task-cask-2~all~insert_cask~default-1-null.142^v93^chatsearchT3_1"}}] [.reference_item style="max-width: 50%"] - *3* [N皇后问题(Python实现)](https://blog.csdn.net/qq_43235359/article/details/90605468)[target="_blank" data-report-click={"spm":"1018.2226.3001.9630","extra":{"utm_source":"vip_chatgpt_common_search_pc_result","utm_medium":"distribute.pc_search_result.none-task-cask-2~all~insert_cask~default-1-null.142^v93^chatsearchT3_1"}}] [.reference_item style="max-width: 50%"] [ .reference_list ]
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值