递归解决全排列和幻方
来源:互联网 发布:文件还原软件 编辑:程序博客网 时间:2024/06/06 02:57
何为全排列,我想这个就不用多解释了吧,如果真不知道,可以自行上网查询。现在的重点是如何编程实现它,简要介绍一下我的全排列的递归算法思想:若用字符数组a[n]来存储数据,先固定a[0]到a[k](k从0到n-1),再生成a[k+1]到a[n-1]的全排列(具体采用交换元素的步骤来实现)。
C代码如下
#include<stdio.h>#include<string.h>void permute(char *a, int num, int i);void permute(char *a, int num, int i){ int j; char temp; if(i >= num){ puts(a); }else{ for(j = i; j < num; j++){ temp = a[i];//交换a[i]和a[j] a[i] = a[j]; a[j] = temp; permute(a, num, i+1); temp = a[i];//回溯 a[i] = a[j]; a[j] = temp; } }}int main(void){ char a[] = "ABC"; permute(a, strlen(a), 0); return 0;}
现在我们可以借助上述全排列的算法思想,实现输出任意阶幻方的所有情形。比如三阶幻方,可用1-9依次填满所有幻方格子,然后使用全排列,每次排列记得检查只有符合幻方要求的情形才输出来。
c++代码如下:
#include <iostream>#include <vector>using namespace std;void createMagicSquare(vector< vector<int> > &matrix, int n, int i, int sum);int isEqualToSum(vector< vector<int> > matrix, int n, int sum);void showMagicSquare(vector< vector<int> > matrix, int n);void showMagicSquare(vector< vector<int> > matrix, int n){ static int count; printf("第%d种情形:\n", ++count); for(int i = 0; i < n; i++){ for(int j = 0; j < n; j++) printf("%2d", matrix[i][j]); cout << endl; } }int isEqualToSum(vector< vector<int> > matrix, int n, int sum){ int rowSum, i, j; vector<int> colSum(n); int diagonalSum[2] = {0};//两条对角线的和 for(i = 0; i < n; i++){ for(j = rowSum = 0; j < n; j++){ rowSum += matrix[i][j]; if(rowSum > sum)//当每行当前元素之和大于sum时已经不满足幻方要求 return 0; colSum[j] += matrix[i][j]; if(colSum[j] > sum)//当每列当前元素之和大于sum时已经不满足幻方要求 return 0; if(i == j) diagonalSum[0] += matrix[i][j]; if(i+j == n-1) diagonalSum[1] += matrix[i][j]; //当每条对角线当前元素之和大于sum时已经不满足幻方要求 if(diagonalSum[0] > sum || diagonalSum[1] > sum) return 0; } if(rowSum != sum) return 0; } for(j = 0; j < n && colSum[j] == sum; j++) ; if(j != n) return 0; if(diagonalSum[0] != sum || diagonalSum[1] != sum) return 0; return 1;}void createMagicSquare(vector< vector<int> > &matrix, int n, int i, int sum){ int temp, j; int num = n * n; if(i >= num && isEqualToSum(matrix, n, sum)){ showMagicSquare(matrix, n); }else{ for(j = i; j < num; j++){//二维矩阵用一个下标表示 temp = matrix[i/n][i%n]; matrix[i/n][i%n] = matrix[j/n][j%n]; matrix[j/n][j%n] = temp; createMagicSquare(matrix, n, i+1, sum); temp = matrix[i/n][i%n]; matrix[i/n][i%n] = matrix[j/n][j%n]; matrix[j/n][j%n] = temp; } }}int main(){ int n, sum, i, j; cout << "请输入幻方阶数:"; cin >> n; sum = n*(n*n + 1)/2;//n阶幻方要求的每行每列每条对角线的和 vector< vector<int> > matrix(n); for(i = 0; i < n; i++) matrix[i].resize(n); //将1到n*n填入幻方格子 for(i = 0; i < n; i++) for(j = 0; j < n; j++) matrix[i][j] = i*n + j + 1; createMagicSquare(matrix, n, 0, sum); return 0;}
不过这种实现幻方的算法时间复杂度太大(O(N!),N为数据规模即幻方的格子数),如过追求效率,该算法实在是不可取。有一种连续摆放法,幻方要根据阶数分三种情况:奇数,能被4整除的偶数和不能被4整除的偶数;不同的情形数字摆放的方法不同,其时间复杂度为O(N),有兴趣的读者可以自行上网查阅,此处我就不再细说该方法。但是这种连续摆放法只能输出幻方的一种情形,如过要输出所有情形,就得进行翻转对折等步骤,而当阶数为4时,就已经很难想尽所有变换方法,故当输出所有情形时,连续摆放法也很难实现。
文章若有不足处,还请大家指正!谢谢!
0 0
- 递归解决全排列和幻方
- 递归解决全排列
- 递归解决全排列问题
- 递归解决全排列问题
- 全排列枚举和递归
- 全排列和去重全排列---递归实现
- 递归输出全排列和全组合
- 递归分治解决全排列问题
- 递归解决全排列生成算法
- java使用递归解决全排列问题
- 递归解决全排列生成算法
- 递归解决全排列生成算法
- 递归解决全排列生成算法
- 利用递归解决全排列问题
- Java递归解决全排列问题
- 递归解决全排列问题+详细图解递归执行
- 递归实现全排列和组合
- 全排列:穷举法和递归法
- 回调函数思想
- C++基础知识(四)—— 操作符/运算符
- 斯坦福大学机器学习笔记(2)
- ssh远程
- JavaScript基础[用途、基本使用、批量产生对像、对象调用、对批量生产对象进行验证、语法的灵活性、js的内置对象]
- 递归解决全排列和幻方
- LeetCode:Permutations II
- [从头学python] 第08节 http以及urllib的盘点
- C++基础知识(五)—— 基本输入输出
- BP神经网络
- rpm 安装zabbix遇到的依赖问题和解决方法
- subling插件 安转教程
- iOS Document Interaction 编程指南
- 近200篇机器学习&深度学习资料分享(含各种文档,视频,源码等)