【搜索与回溯算法】N皇后问题(详细)

9 篇文章 1 订阅
2 篇文章 0 订阅

学习搜索与回溯

搜索与回溯,是递归的一种重要形式,只要学好回溯,我们就能在一些类似于求方案数、走迷宫类的题目

我们只要学会了回溯,就好比站在了递归这个巨人的肩膀上

搜索与回溯学会了结构,就可以横跨“递归”大道

这是结构↓↓↓

C++:

#include<iostream>
using namespace std;
void dfs(int k){//层数
    if(达到目的) 输出(或者方案数+1else{
    	for(遍历所有的算符){
    		if(没有用到){
    			标记
    			dfs(k+1)//下一层递归
    			回溯
    		}
    	}
    }
}

Python:

def dfs(k):
	global ans#方案数
	if(达到目的) :输出或ans+=1
	else:
		for i in 所有的算符:
			if(没有用到):
				标记
				dfs(k+1)#递归下一层
				回溯
			
	

JavaScript:

function dfs(k){
	if(达到目的)输出或ans+1
	else{
		for(遍历所有的算符){
			if(没有用到){
				标记
				dfs(k+1)
				回溯
			}
		}
	}
}

样例题目

题目描述

在一个nXn的国际象棋棋盘上放置n(n<=12)个皇后,使它们不能互相攻击(即任意两个皇后不能在同一行、同一列或同一对角线上)。试求出所有方法。

输入输出格式

输入

输入一个数n .(n<=12)

输出

输出所有的排列方案总数。

输入输出样例

输入

4

输出

2

本题思路

注意事项:

·1、需要用到深搜格式
·2、可以用一维数组(列表)来表示每个王后所放的位置,k层递归就是第k行
·3、判断是否放置合法:
1、斜着放合法:行列是否差值相等,如:|x1-x2|==|y1-y2|
2、列数放合法:遍历所有放过的Ai不相等
3、同行放合法:不可能不合法,因为递归层数就是行数
·4、如果层数(行数)> N 则方案数+1(调试时可以输出每次放的地方)并结束此次函数执行(return)
·5、记住了就可以写代码了 😉😉😃😃

代码模块

我们可以先简单的进行一个模板,简单的输入输出,最后解决dfs部分

C++

#include<iostream>
#include<cmath>
using namespace std;
int n,ans,a[13];
void ba(int k){
	if(k>n){
		ans++;
		return;
	}else{
		for(int j=1;j<=n;j++){
			int bk=0;
			for(int i=1;i<k;i++){
				if((a[i]==j)||(abs(k-i)==abs(j-a[i]))){
					bk=1;
					break;
				}
			}
			if(!bk){
				a[k]=j;
				ba(k+1);
				a[k]=0;
			}
		}
	}
}
int main()
{
	cin>>n;
	ba(1);
	cout<<ans;
	return 0;
}

Python:

ans = 0
n = int(input())
a = []
def dfs(k):
   global ans,n,a
   if k == n:
       ans+=1
       return
   for j in range(0,n):# 选列
       flag=True
       for i in range(0,k):
           if a[i]==j or abs(i-k)==abs(a[i]-j):
               flag=False
               break
       if flag:
           a.append(j)
           dfs(k+1)
           a.pop()
dfs(0)
print(ans)

JS:
这个可以自己转,跟这两个语言的代码差不多,因为我有些不会

能不能点个赞再走 😉 😃

  • 5
    点赞
  • 1
    收藏
    觉得还不错? 一键收藏
  • 0
    评论
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值