n皇后问题(递归+回溯)

回溯与递归

递归:递归算法的实质是把问题分解成规模缩小的同类问题的子问题(分治),然后递归调用方法来表示问题的解。
回溯:按选优条件向前搜索,以达到目标。但当探索到某一步时,发现原先选择并不优或达不到目标,就退回一步重新选择,这种走不通就退回再走的技术为回溯法。通过剪枝可以大幅减少解决问题的计算量。

全排列(1~n)

给出数字n,打印1~n的所有可能排列。

基本思路

设置数组P存储所求排列,hashTable数组作为标记数组,标记数字是否已加入排列。假设当前已经填好了P[1]-P[index-1],正准备填P[index]。于是枚举1-n,如果当前枚举到的数字x不在P[1]~P[index-1]中,那么把它填入P[index],然后处理P的第index+1位(递归)。当index = n + 1时,显然P[1]-P[n]已填好,进入递归边界,进行输出。

这里设n=3,代码如下:
#include <cstdio>
const int maxn = 11;

int n, P[maxn], hashTable[maxn] = {
   false};

void generateP(int index){
    //处理第index号位 
	if(index == n + 1){
    //已经处理完1~n位 
		for(int i = 1; i <= n; i++){
   
			printf("%d", P[i]);
		}
		printf("\n");
		return ;
	}
	for(int x = 1; x <= n; x++){
    //试图将x填入P[index] 
		if(hashTable[x] == false){
    //x不在P中 
			P[index] = x;  
			hashTable[x] = true;
			generateP(index + 1
  • 1
    点赞
  • 8
    收藏
    觉得还不错? 一键收藏
  • 0
    评论
n皇后问题是指在一个n×n的棋盘上放置n个皇后,使得每行、每列和对角线上都只有一个皇后。这个问题可以使用递归算法来解决。 算法流程: 1.选定一个起始行,从该行开始逐行遍历每一行。 2.在当前行中,逐一尝试每一个位置,如果该位置可以放置皇后,则继续递归下一行。 3.如果下一行无法放置皇后,则回溯到当前行,尝试下一个位置。 4.如果所有位置都尝试过,仍然无法放置皇后,则回溯到上一行,尝试上一行的下一个位置。 5.重复步骤1-4,直到所有皇后都被放置。 代码实现: ```python def solveNQueens(n): def backtrack(row=0, diagonals=set(), anti_diagonals=set(), cols=set()): if row == n: result.append(list(board)) return for col in range(n): diagonal = row - col anti_diagonal = row + col if col in cols or diagonal in diagonals or anti_diagonal in anti_diagonals: continue board[row][col] = 'Q' cols.add(col) diagonals.add(diagonal) anti_diagonals.add(anti_diagonal) backtrack(row + 1, diagonals, anti_diagonals, cols) board[row][col] = '.' cols.remove(col) diagonals.remove(diagonal) anti_diagonals.remove(anti_diagonal) board = [["."] * n for _ in range(n)] result = [] backtrack() return result ``` 这里使用了一个回溯算法,其中参数row表示当前正在遍历的行数,diagonals表示在主对角线上的皇后所在的位置,anti_diagonals表示在副对角线上的皇后所在的位置,cols表示在列上已经放置了皇后的位置。

“相关推荐”对你有帮助么?

  • 非常没帮助
  • 没帮助
  • 一般
  • 有帮助
  • 非常有帮助
提交
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值