全排列算是一种比较经典的问题,在这记录一下。
可重复全排列
1654.全排列问题
题面描述
输入 n n n输出 1 1 1, 1 ∼ n 1 \sim n 1∼n个数的全部排列。全部排列中,数字可以重复 。
例如输入 3 3 3 ,输出全部排列的结果如下:
111 、 112 、 113 、 121 、 122 、 123 、 131 、 132 、 133 、 211 、 212 、 213 、 221 、 222 、 223 、 231 、 232 、 233 、 311 、 312 、 313 、 321 、 322 、 323 、 331 、 332 、 333 111、112、113、121、122、123、131、132、133、211、212、213、221、222、223、231、232、233、311、312、313、321、322、323、331、332、333 111、112、113、121、122、123、131、132、133、211、212、213、221、222、223、231、232、233、311、312、313、321、322、323、331、332、333
输入
输入一个数
n
n
n,要求输出
1
∼
n
1 \sim n
1∼n的全排列。
n
n
n
(
1
≤
n
≤
6
)
(1 \leq n \leq 6 )
(1≤n≤6)
输出
按照由小到大输出 1 ∼ n 1 \sim n 1∼n的所有全排列
样例
输入
2
输出
1 1
1 2
2 1
2 2
思路
这颗树是模拟递归的过程,丑是丑了点, 根据样例,咱们可以挖一个空,可以从
1
∼
2
1 \sim 2
1∼2来依次填入,就像第二层一样,因为可以重复填入,所以又从
1
1
1开始填到
2
2
2。这样下去,当然,题目要求从小到大,可不能像这个图一样从
22
22
22到
21
21
21。
代码
#include<iostream>
using namespace std;
int n;
int a[10];
void print(){//输出,分开就没有那么冗余
for(int i=1;i<=n;i++){
cout<<a[i];
}
cout<<"\n";
}
void dfs(int k){//进行全部搜索
for(int i=1;i<=n;i++){//从1~n全部填进去
a[k]=i;//储存数据,因为是在同一位置转换,所以不用归零
if(k==n){//数量达到了n个
print();//输出
}else{
dfs(k+1);//继续填入
}
}
}
int main(){
cin>>n;
dfs(1);
return 0;
}
不可重复全排列
1308.全排列的结果
题面描述
从键盘中读入一个数
n
n
n,请输出
1
∼
2
1 \sim 2
1∼2中所有整数的全排列,按照由小到大输出结果,每组的
n
n
n个数之间用空格隔开。
全排列的含义:从
n
n
n个不同的元素中任取
m
m
m
(
m
≤
n
)
(m \leq n)
(m≤n)个元素,按照一定的顺序排列起来,叫做从
n
n
n个不同元素中取出
m
m
m个元素的一个排列。当
m
=
n
m=n
m=n时所有的排列情况叫全排列。
如当
n
=
3
n=3
n=3时,全排列的结果为:
1 2 3
1 3 2
2 1 3
2 3 1
3 1 2
3 2 1
输入
一个整数 n ( 1 ≤ n ≤ 6 ) ; n(1 \leq n \leq 6); n(1≤n≤6);
输出
1 ∼ n 1 \sim n 1∼n中所有的全排列结果,按照由小到大输出,每行 n n n个数。
样例
输入
3
输出
1 2 3
1 3 2
2 1 3
2 3 1
3 1 2
3 2 1
思路
关于这道题,跟上面的一道题类似,区别就是一个可重复,一个不可重复,那么只需要增加一个判断回溯即可,判断是否选过。
代码
#include<iostream>
using namespace std;
int n;
int a[10];
bool flag[10];//标记数组
void print(){//方便
for(int i=1;i<=n;i++){
cout<<a[i]<<" ";
}
cout<<"\n";
}
void dfs(int k){
for(int i=1;i<=n;i++){
if(flag[i]==false){//还没有选过
a[k]=i;//放入
flag[i]=true;//改变状态,变成选过的
if(k==n){//数量一样,输出
print();
}else{
dfs(k+1);//往下选
}
flag[i]=false;//回来后撤销标记
}
}
}
int main(){
cin>>n;
dfs(1);
return 0;
}
The End
有不专业或错误处,请指出。