2022-11-20 Acwing每日一题
本系列所有题目均为Acwing课的内容,发表博客既是为了学习总结,加深自己的印象,同时也是为了以后回过头来看时,不会感叹虚度光阴罢了,因此如果出现错误,欢迎大家能够指出错误,我会认真改正的。同时也希望文章能够让你有所收获,与君共勉!
排列数字
给定一个整数 n,将数字 1∼n 排成一排,将会有很多种排列方法。
现在,请你按照字典序将所有的排列方法输出。
输入格式
共一行,包含一个整数 n。
输出格式
按字典序输出所有排列方案,每个方案占一行。
数据范围
1≤n≤7
输入样例:
3
输出样例:
1 2 3
1 3 2
2 1 3
2 3 1
3 1 2
3 2 1
算法原理
常见的搜索方法,DFS和BFS,这里我们要用DFS求解。
用一个树来表示搜索过程,对于每一位我们遍历每一个数字在这一位,用path[i]
来存储,表示第i位,path[i]
表示第i位上的数字,在当前状态下我们继续搜索下一位该放什么,并且我们还要定义一个数字哈希st[i]
表示这一位我们是否用过,如果用过我们就选择下一个数字,直到所有数字都用过时,就说明已经形成了一个组合数,并把它输出,需要注意的是当我们搜索完后一定要进行状态回溯,不然这一颗树的状态就会到另一棵树上。
代码实现
#include <iostream>
#include <cstring>
#include <algorithm>
using namespace std;
const int N = 10;
int path[N];
bool st[N];
int n;
void dfs(int u){
if(u == n){ // 当所有数字都被用过后说明就形成了一个组合数
for(int i=0; i < n ; ++i) cout << path[i]<< ' '; // 输出每一行
puts("");
return ;
}
for(int i=1;i <= n ;++i){
// 因为要搜索所有的数字,所以要将所有的数字都放进去且在同一情况下不放已经标记过的数字
if(!st[i]){
path[u] = i; // 第u位上的数字是i
st[i] = true;
dfs(u+1); // 所以标记完后再给上一层选择时要进行恢复现场,回溯
st[i] = false; // 现场回溯
}
}
}
int main()
{
cin >> n;
dfs(0);
return 0;
}