洛谷 P1706 全排列问题
以下有两种解法,一种是深度优先搜索,一种是利用c++中的库函数next_permutation()函数
人比较懒,所以下面就讲解一下稍微简单易懂的第二种解法
简单描述一下next_permutation()函数的用法(个人理解)
bool next_permutation(iterator start,iterator end)
函数返回一个bool类型的值,参数是迭代器起始到终止
通常是以数组为函数的操作对象,函数会改变数组中元素的位置,自动进行排列,如果当前数组中的下一个排列存在则返回true 否则返回false
举个例子: 对1,2,3 进行全排列(结果按字典升序)
结果为:
1 2 3
1 3 2
2 1 3
2 3 1
3 1 2
3 2 1
其中1 2 3为第一组排序,3 2 1为最后一组排序,当数组中的数列为3 2 1时下一步操作时next_permutation()函数将会返回false,因为3 2 1已经是最后一组排列了,在它后面已经没有其他的排列了。
所以,通常情况下用next_permutation()函数求全排列时,数组最初值一定要是全排列中最小的排列(在上面的例子中也就是1 2 3)
如果初始时数组中顺序不是最小的那组排列,则用next_permutation()函数求排列时,只能得到初始排列后面比初始排列字典序大的排列
使用格式
do{ for(int i=1;i<=n;i++) cout<<s[i]; cout<<endl; }while(next_permutation(s,s+n));
有了以上知识,对于洛谷这道全排列的题解起来就很简单了
以下代码包括 深度优先搜索版本 和 next_permutation()函数版本
#include<bits/stdc++.h> using namespace std; int res[10]; int vis[10]; int n; void dfs(int step) { if (step == n + 1) { for (int i = 1; i <= n; i++) printf("%5d",res[i]); cout << endl; return; } for (int i = 1; i <= n; i++) { if (vis[i] == 0) { res[step] = i; vis[i] = 1; dfs(step + 1); vis[i] = 0; } } } //深度优先搜索 void test() { cin >> n; dfs(1); } //next_permutation()全排列函数 void test01() { int n; cin>>n; int s[10]={0,1,2,3,4,5,6,7,8,9}; do{ for(int i=1;i<=n;i++) printf("%5d",s[i]); cout<<endl; }while(next_permutation(s+1,s+n+1)); } int main() { // test(); test01(); return 0; }