1、题目描述
把1 ~ n这n个整数排成一行后随机打乱顺序,输出所有可能的次序。
输入格式
输入一个整数n。
输出格式
按照从小到大的顺序输出所有方案,每行1个。首先,同一行相邻两个数用一个空格隔开。其次,对于两个不同的行,对应下标的数一一比较,字典序较小的排在前面。
数据范围
1n
9
输入样例
3
输出样例
1 2 3 1 3 2 2 1 3 2 3 1 3 1 2 3 2 1
2、题目解析
如下如,采用dfs深度递归搜索树,加入n=3时,考虑每一个位置放哪个数,可以一直递归下去,直到最后一个位置也放置好了。维护两个状态数组,一个用来记录位置,一个用来记录数值。
代码如下(时间复杂度O(n!)) :
#include<cstdio>
#include<cstring>
#include<iostream>
#include<algorithm>
using namespace std;
/**
* 方法采用
* 依次枚举每个位置放哪个数
*
*/
int n;
const int N = 9;
int datas[N] = {0}; // 数据状态数组,0表示还没有被选择,1表示被选择了
int loc[N] = {0}; // 位置状态数组,0表示还没有被安排,否则表示被安排了
void dfs(int m){ // m表示到第几个位置了
if(m > n){ // 到深度递归的底部了,输出来并且结束递归
for(int i = 1; i <= n;++i)
printf("%d ",loc[i]);
getchar();
printf("\n");
return;
}
for(int i = 1; i<= n;++i){ // 依次枚举当前位置可以选择的数据,采用dfs深度递归
if(datas[i] == 0){
loc[m] = i; // 当前位置安排当前未选择的最小的数
datas[i] = 1; // 当前被选中的数的状态变为1
dfs(m + 1);
// 现场恢复
datas[i] = 0;
loc[m] = 0;
}
}
}
int main()
{
scanf("%d",&n);
dfs(1);
return 0;
}
备注:该题和递归实现指数型枚举有点类似,都采用dfs,该题以某个位置放置哪个数值来递归,而递归实现指数型枚举是以该位置的数是否取为递归。