一、题目描述
输入一个数n,请你写出1~n的全排列。
全排列定义:从n个不同元素中任取m(m≤n)个元素,按照一定的顺序排列起来,叫做从n个不同元素中取出m个元素的一个排列。当m=n时所有的排列情况叫全排列。
例如:
输入
3
输出
123
132
213
231
312
321
二、算法分析
对于这类题,我们很直接了当的就知道可以用暴力枚举去完成算法,具体做法就是从1~3中任选一个数放在第一位,之后再从剩余的两个里面任选一个放在第二位,最后一个放在最后一位。不过,今天我们要介绍一个更“高级”的算法——递归算法。
递归算法主要有三个组成部分:初始化、循环体(递归函数)、递归终止条件;
初始化:即将递归所需要的已经明确的数据储存在需要的、合适的容器中,并申请一些辅助变量配合进行递归算法的实现;
循环体:也叫递归函数,是递归算法的主体,它的作用就是不断调用自己,通过取不同的值来达到我们所需要的结果;
递归终止条件:是递归算法的重中之重,它是结束递归算法的基石,如果没有它,算法会一直进行下去。
比如上面的算法,它的循环体就是对1~3进行连续存取,通过存取的顺序来对数据排序。但是,有一个问题,就是我该如何判定这个数用没用过,为了判断这个数,我们需要用一个tof数组(ture or false)来进行标记,也就是初始化一个tof数组,同时,我还需要初始化另一个数组ans[]来存储已经标记好的数。那么递归结束的条件是什么呢,就是这个ans[]的长度为3,此时我们就要输出ans。要特别注意的是,每当我们递归调用完一次后,需要将我们已经变动过的数据复原,以便进行下一次循环。
三、代码
#include <bits/stdc++.h>
using namespace std;
int tof[10];
int ans[10];
int n;
void dp(int num) {
if (num > n) { //终止条件就是ans长度大于三,因为我们是从1开始进行的,如果从0开始进行,则需
要加一个等于
for(int i=1;i<=n;i++){ //注意,下标要从1开始
i==1?(cout<<ans[i]):(cout<<' '<<ans[i]); //多目运算,格式规范化
cout<<endl;
return;
}
for (int i = 1; i <= n; i++) { //从1到n选择一个数进行排列
if (!tof[i]) { //判断这个数是否被选过,选过则跳过,没有则存储下来并且标记为1
tof[i] = 1; //标记为已选
ans[num] = i; //存储下来
dp(num+1); //存储后,数组长度加一,然后继续选择
tof[i] = 0; //递归结束,数据复原
}
}
}
int main() {
cin>>n;
dp(1); //ans数组长度从1开始增加
return 0;
}
同时,这个答案也是类似题目的一种模板,请看下面一题:
洛谷P1008 [NOIP1998 普及组] 三连击
题目背景
本题为提交答案题,您可以写程序或手算在本机上算出答案后,直接提交答案文本,也可提交答案生成程序。
题目描述
将 1,2,…,9共 9个数分成 3 组,分别组成 3 个三位数,且使这 3 个三位数构成 1:2:3的比例,试求出所有满足条件的 3 个三位数。
输入格式
无
输出格式
若干行,每行 3 个数字。按照每行第 1 个数字升序排列。
输入输出样例
输入 #1复制
无
输出 #1复制
192 384 576 * * * ... * * * (剩余部分不予展示)
根据上述知识,我们可以很快写出代码
#include <bits/stdc++.h>
using namespace std;
int tof[10];
int sumnum[10];
void dp(int num) {
if (num > 9) {
//全排列完成后进行数据的计算
int a = sumnum[1] * 100 + sumnum[2] * 10 + sumnum[3];
int b = sumnum[4] * 100 + sumnum[5] * 10 + sumnum[6];
int c = sumnum[7] * 100 + sumnum[8] * 10 + sumnum[9];
if (a * 2 == b && a * 3 == c) { //终止条件
cout << a << ' ' << b << ' ' << c << endl;
return;
}
}
for (int i = 1; i <= 9; i++) {
if (!tof[i] ) {
tof[i] = 1;
sumnum[num] = i;
dp(num+1);
tof[i] = 0;
}
}
}
int main() {
dp(1);
return 0;
}