题目描述
给定一个数字 ,请按照字典序输出排列 的全排列。
输入格式
一个整数 。
输出格式
一行输出一个结果,按照字典序从小到大排列。
样例输入1
3
样例输出1
1 2 3
1 3 2
2 1 3
2 3 1
3 1 2
3 2 1
思路
定义一个位图(bitset)vis来记录哪些数字已经被使用过,以及一个数组a来存储当前的排列。这两者都是全局变量,可以在整个程序中访问。
然后,我们在main函数中获取用户输入的数字n,这个数字表示我们要生成多少个元素的全排列。vis.reset()是将所有位设置为0,表示一开始所有的数字都没有被使用过。
调用dfs函数开始生成全排列。这个函数接收一个参数d,表示当前正在处理第d个位置的元素。在dfs函数中,我们首先检查是否已经处理完所有位置的元素(即d == n + 1)。如果是,那么我们就输出当前的排列,并返回。
如果还有位置没有处理,我们就遍历所有的数字,尝试将它们放在当前位置。对于每一个数字,我们首先检查它是否已经被使用过(即vis[i]是否为1)。如果没有被使用过,我们就标记它为已使用,将它放在当前位置,然后递归地处理下一个位置。递归返回后,我们需要取消对当前数字的使用标记,以便于它可以被放在其他位置。这就是典型的回溯思想。
AC代码
#include <bitset>
#include <iostream>
#define AUTHOR "HEX9CF"
using namespace std;
const int N = 10;
bitset<N> vis;
int a[N];
int n;
void dfs(int d) {
if (d == n + 1) {
for (int i = 1; i <= n; i++) {
cout << a[i] << " \n"[i == n];
}
return;
}
for (int i = 1; i <= n; i++) {
if (!vis[i]) {
vis[i] = 1;
a[d] = i;
dfs(d + 1);
vis[i] = 0;
}
}
}
int main() {
ios::sync_with_stdio(0);
cin.tie(0);
cout.tie(0);
vis.reset();
cin >> n;
dfs(1);
return 0;
}