全排列问题与n皇后问题
来源:互联网 发布:win查看端口占用 编辑:程序博客网 时间:2024/05/22 15:02
全排列问题
基本思想:
从递归的角度考虑,将“输出从1~n的全排列”分为若干个子问题:“输出以1为开头的全排列”,“输出以2为开头的全排列”…… 于是不妨设定一个数组P,用来存放当前排列;再设定一个散列数组hashTable,其中hashTable[x]当整数x已经在数组P中时为true。
递归边界:当index达到n+1时,说明P的第1~n位都已经填好了,把数组P输出,表示生成了一个排列,然后直接return即可。
基本代码:n=3
#include<cstdio>const int maxn = 11;//p为当前排列,hashTable记录整数x是否已经在p中int n, p[maxn], hashTable[maxn] = { false };//当前处理排列的index号位void generateP(int 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++) //枚举1~n,试图将x填入p[index] { if (hashTable[x] == false) //如果x不在P[0]~P[index-1]中 { p[index] = x; //令p的第index位为x,即把x加入当前排列 hashTable[x] = true; //记x已在P中 generateP(index + 1); //处理排列的第index+1号位 hashTable[x] = false; //已处理完P[index]为x的子问题,还原状态 } }}int main(){ n = 3; generateP(1); return 0;}
n皇后问题
问题描述:在一个n*n的国际象棋棋盘上放置n个皇后,使得这n个皇后两两均不在同一行、同一列、同一对角线上。
递归法方案:
基本思想与全排列问题类似,只不过在达到递归边界的情况下加了判断是否存在同一列的方法。
代码如下:
#include<cstdio>#include<cmath>const int maxn = 11;int n, P[maxn], hashTable[maxn] = { false };int count = 0;int generateP(int index){ if (index == n + 1) { bool flag = true; //flag为true表示当前排列合法 for (int i = 1; i <= n; i++) { for (int j = i + 1; j <= n; j++) { if (abs(i - j) == abs(P[i] - P[j])) //如果在一条对角线上 { flag = false; //不合法 } } } if (flag) { for (int i = 1; i <= n; i++) { printf("%d ", P[i]); } printf("\n"); count++; } return count; } for (int x = 1; x <= n; x++) { if (hashTable[x] == false) { P[index] = x; hashTable[x] = true; generateP(index + 1); hashTable[x] = false; } }}int main(){ n = 5; printf("共有%d种方法\n",generateP(1)); return 0;}
回溯法:
基本思想:上一个方法是相当暴力的,可以发现,可能存在放置一部分皇后就出现了不合法的情况,所以就没有必要接着往下进行递归了。就产生了回溯法。
代码:
#include<cstdio>#include<cmath>const int maxn = 11;int n, P[maxn], hashTable[maxn] = { false };int count = 0;int generateP(int index){ if (index == n + 1){ for (int i = 1; i <=n; i++) //能达到这里一定是合法的 { printf("%d ", P[i]); } printf("\n"); count++; return count; } for (int x = 1; x <=n; x++) { if (hashTable[x]==false) { bool flag = true; //flag表示当前皇后不会跟之前的皇后冲突 for (int pre = 1; pre < index; pre++) //遍历之前的皇后 { //第index列的皇后的行号为x,第pre列的皇后行号为P[pre] if (abs(index-pre)==abs(x-P[pre])) { flag = false; //与之前的皇后在一条对角线,冲突 break; } } if (flag) { P[index] = x; hashTable[x] = true; generateP(index + 1); hashTable[x] = false; } } }}int main(){ n = 5; int i = generateP(1); printf("%d\n",i); return 0;}
阅读全文
0 0
- 全排列问题与n皇后问题
- C++ 输出全排列 简单递归 N皇后问题
- N皇后问题(回溯VS全排列)
- 八皇后问题的全排列解法
- 八皇后问题和字符串全排列
- 全排列方法求解八皇后问题
- 八皇后问题的全排列解法
- 八皇后问题--全排列法[Java]
- N个数全排列问题
- 用全排列方法解决N皇后问题(Leetcode 51)
- 字符串排列与八皇后问题
- N*N皇后问题
- 全排列与组合问题
- 全排列与组合问题
- 全排列问题:序号与排列转换
- 从零开始的暴搜复习生活—DFS(CODE[VS] 1116 四色问题 1294 全排列 1295 N皇后问题)
- n皇后问题的两种方法:常规的回溯法和利用全排列的回溯法
- 递归回溯问题的四道经典题:N皇后,组合,全排列,二叉树路径和
- 强化学习——A3C,GA3C
- xlistview上拉刷新,下拉加载
- Blood groups
- 在O(1)时间复杂度删除链表节点
- charles抓包
- 全排列问题与n皇后问题
- 创建单链表并赋值,要求遍历能输出1~9
- Spring4 bean 关系
- Sqoop1 安装及Hive/Hbase数据与Mysql数据互导(九)
- nyoj 456 邮票分你一半
- PAT-Build A Binary Search Tree
- 《Android Studio 中的java文件出现“R”爆红怎么办?》
- java二维数组A.length和A[i].length的区别
- Hpu-1412QAQ & 君临天下 || 天行九歌 【区间】[多校联萌]