next_permutation用法
- 函数类型:bool
- 函数作用:生成给定序列的下一个较大序列,直到序列按降序排列为止。
- 头文件:包含在
- 注意:
<1> 希望生成所有的排列方式,一般与sort函数结合,先用sort升序排列,再调用next_permunation函数。
<2> 使用do~while,原因:直接调用while+next_permutation函数,会跳开初始的排序。 - 简单列子
# include <iostream>
# include <algorithm>
using namespace std;
int main()
{
int a[] = { 3,1,2 };
sort(a, a + 3); //默认升序排列
do {
for (int i = 0; i < 3; i++) {
cout << a[i] << " ";
}
cout << endl;
} while (next_permutation(a, a + 3)); //第一个参数对应数组首,第二个参数对应数组尾
return 0;
}
运行结果
1 2 3
1 3 2
2 1 3
2 3 1
3 1 2
3 2 1
- 具体应用
题目:
将 1, 2, ······ , 9 共9个数分成 3 组,分别组成 3 个三位数,且使这 3 个三位数构成 1 : 2 : 3 的比例,试求出所有满足条件的 3 个三位数。
输出格式:
若干行,每行 3 个数字。按照每行第 1 个数字升序排列。
完整代码:
# include <iostream>
# include <algorithm>
using namespace std;
int main()
{
int a[] = { 1,2,3,4,5,6,7,8,9 }; //按升序排列
int x1, x2, x3;
do {
x1 = 100 * a[0] + 10 * a[1] + a[2];
x2 = 100 * a[3] + 10 * a[4] + a[5];
x3 = 100 * a[6] + 10 * a[7] + a[8];
if (x2 == 2 * x1 && x3 == 3 * x1) { //判断是否满足3:2:1
cout << x1 << " " << x2 << " " << x3 << endl;
}
} while (next_permutation(a, a + 9));
return 0;
}
运行结果:
192 384 576
219 438 657
273 546 819
327 654 981
DFS深度搜索
模板
void dfs(int step)
if(到达目的地)
{
输出解;
return;
}
合理的剪枝操作
for(int i=1;i<=枚举数;i++)
{
if(满足条件)
{
更新状态位;
dfs(step+1);
回复状态位;
}
}
#include<iostream>
using namespace std;
int a[10],b[10];//a[10]用来记录排序结果,b[i]用来标记是否该数被选择
int n;
void dfs(int k)
{
if(k==n)
{
for(int i=0;i<n;i++)
cout<<a[i]<<" ";
cout<<endl;
return ;
}
for(int i=1;i<=n;i++)
{
if(b[i]==0)
{
a[k]=i;
b[i]=1;//进行标记,防止重复
dfs(k+1);
b[i]=0;//回溯后恢复被标记的数据
}
}
}
int main()
{
cin>>n;
dfs(0);
return 0;
}
输出结果;
3
1 2 3
1 3 2
2 1 3
2 3 1
3 1 2
3 2 1
总结:
如果选出的数注重顺序(即123与132表示的意义不同),采用next_permutation函数与dfs(枚举时采用for(i=1;i<=n;i++),并用visited[]标记)函数更好。
如果选出的数不注重顺序(即123与321表示的意义相同),采用dfs(枚举时采用for(int i=start;i<=n;i++)函数)