N-Queens(递归回溯+迭代回溯)
来源:互联网 发布:祥南行书体 mac 编辑:程序博客网 时间:2024/06/07 20:54
回溯法算法思想:
回溯法在问题的解空间树中,按深度优先策略,从根节点出发搜索解空间树;
算法搜索至解空间树的任一节点时,先判断该节点是否包含问题的解;
如果肯定不包含,则跳过对以该节点为根的子树的搜索,逐层向其祖先节点回溯;
否则,进入该子树,继续按深度优先策略搜索。
回溯法解题模板:
针对所给问题,定义问题的解空间;
确定解空间结构;
以深度优先方式搜索解空间;
按约束条件进行剪枝。
总结递归回溯模板和迭代回溯模板:
/*递归回溯模板*/void backtrack(){ if(t>n) //t表示递归深度,n控制递归深度。t>n表示算法已搜索至叶节点 output(x); //记录或输出得到的可行解x else { //f(n,t)和g(n,t)分别表示在当前扩展结点处未搜索过的子树的起止编号和终止编号 for(int i=f(n,t);i<=g(n,t),i++) { x[t]=h(i); //h(i)表示在当前扩展结点处x[t]的第i个可选值 if(constraint(t) && bount(t)) //当前扩展结点处的约束函数和限界函数 backtrack(t+1); } }}/*迭代回溯模板*/void iterativeBacktrack(){ int i=1; while(t>0) { if(f(n,t)<=g(n,t)) { for(int i=f(n,t);i<=g(n,t);i++) { x[t]=h(i); if(constraint(t) && bount(t)) { if(solution(t)) //判断在当前结点处是否已得到问题的可行解 output(x); else t++; } } } else t--; }}
N-Queens
Problem Description
The n-queens puzzle is the problem of placing n queens on an n×n chessboard such that no two queens attack each other.In the N*N square checkerboard, the N queens are placed so that they do not attack each other (that is, any 2 queens are not allowed in the same row, the same column, nor in a diagonal line with the 45 corners of the checkerboard frame.
Your task is to find out how many legitimate placement methods are available for a given N.
Given an integer n, return all distinct solutions to the n-queens puzzle.
For example,
There exist two distinct solutions to the 4-queens puzzle:
Input
There are a number of lines, each line is a positive integer less than or equal to 20 N, the number of the chessboard and the queen.
Output
Each row has a positive integer indicating the number of queens placed for the corresponding input line.
Sample Input
4
Sample Output
2
题目分析及思路:
棋盘类的题目一般是回溯法。
定义解空间(解的取值范围):
用一个n元向量X=(x1,x2,…..xn)表示,其中,1≤ i≤ n且1≤ xi≤ n,即第n个皇后放在第i行第xi列上。
确定解空间结构
以4皇后为例。
定义约束条件
该题有两个约束:一是不允许2个皇后放在同一列,所以解向量中的x[i]互不相同;二是2个皇后不能放在同一斜线上,这是问题的隐约束。
所以要将这一隐约束化成显约束:盘左上角到右下角的主对角线及其平行线(斜率为-1的各斜线)上,2个下标值的差(行号-列号)值相等;同理斜率为+1的每条斜线上2下标值的和(行号+列号)相等。所以2个皇后放置位置分别是(I,j)和(k,l)且i-j=k-l或i+j=k+l时表示2个皇后处于同一斜线上。即是|i-k|=|j-l|,隐约束就化成了显约束。
用DFS搜索解空间,并按约束条件剪枝,加快搜索速度
算法实现:
递归回溯解题:
#include<iostream>using namespace std;#define N 20int x[N],n,sum=0; //皇后放置列数、个数、可行解个数bool place(int k){ for(int j=1;j<k;j++) { if(x[j] == x[k] || abs(x[j]-x[k]) == abs(k-j)) return false; } return true;}int backtrack(int k){ int i=0; if(k>n) { sum++; } else { for(i=1;i<=n;i++) { x[k]=i; if(place(k)) backtrack(k+1); } return sum; }}int main(){ printf("请输入皇后个数(n<20):"); scanf("%d",&n); printf("放置方法数为:%d\n:",backtrack(1)); return 0;}
迭代回溯解题:
/*迭代回溯*/#include<iostream>using namespace std;#define N 20int x[N],n,sum=0; //皇后放置列数、个数、可行解个数bool place(int k){ for(int j=1;j<k;j++) { if(x[j] == x[k] || abs(x[j]-x[k]) == abs(k-j)) return false; } return true;}int backtrack(){ int k=1; x[1]=0; while(k>0) { x[k]++; //当前列加1的位置开始搜索 while(x[k]<=n && !place(k)) //当前位置是否满足条件 x[k]++; //不满足继续搜索下一位置 if(x[k]<=n) { if(k==n) //最后一个皇后,完成搜索 sum++; else //不是则继续处理下一个皇后 x[++k]=0; } else //回溯 k--; } return sum;}int main(){ printf("请输入皇后个数(n<20):"); scanf("%d",&n); printf("放置方法数为:%d\n",backtrack()); return 0;}
- N-Queens(递归回溯+迭代回溯)
- N-Queens C++递归回溯实现
- 八皇后问题(递归回溯+迭代回溯)
- leetcode---N-Queens---回溯
- 回溯法之递归回溯和迭代回溯
- n Queens Problem(回溯法)
- 【Leetcode】51. N-Queens(回溯)
- 51.leetcode N-Queens(hard)[递归回溯剪枝]
- LeetCode 51. N-Queens 回溯
- 迭代回溯法求解N皇后
- N皇后问题(回溯递归)
- n皇后(递归回溯搜索)
- N皇后(回溯)递归实现
- LeetCode OJ - N-Queens 回溯法
- N-Queens II 回溯法求八皇后
- 52. N-Queens II 回溯算法浅谈
- 51. N-Queens 回溯算法浅谈
- leetcode 51 N-Queens 回溯 万能结构
- 浅析c#委托
- Web安全测试经验
- C#学习笔记
- ZZU15级软工最后一次算法作业
- 第八届蓝桥杯决赛小结
- N-Queens(递归回溯+迭代回溯)
- 「报告」工业互联网信息安全厂商报告-01
- 程序员顶尖和普通就是有5个区别!
- HDU
- ZooKeeper主从模式的三种角色(以Client为例)
- Java 获取本月最后一天
- USACO Section1.3 Mixing Milk
- 动态顺序表部分接口的简易实现
- 什么是ppa