题目来源:洛谷P1706 全排列问题
前言:本人新手小白,代码写的可能不太好,但题解都正确,请慎重使用。
题目描述:
按照字典序输出自然数 1 到 n 所有不重复的排列,即 n 的全排列,要求所产生的任一数字序列中不允许出现重复的数字。
输入格式:
一个整数 n。
输出格式:
由 1∼n 组成的所有不重复的数字序列,每行一个序列。
每个数字保留 5 个场宽。
样例 #1
样例输入 #1
3
样例输出 #1
1 2 3
1 3 2
2 1 3
2 3 1
3 1 2
3 2 1
提示
1≤n≤9。
分析:
怎么说呢,这是一道大佬看了说简单,新手看了挠头,初学者看了躺板板的题,作为一个学递归不久的小白,我看到题也想了很久,但只要捋清思路,这道题还是很简单的。
思路
题中输入3就是把1到3(1,2,3)这三个数进行排列,所以有{1,2,3},{1,3,2},{2,1,3},{2,3,1},{3,1,2},{3,2,1}一共六种。
所以先把基础的先写一下:
#include<iostream>
#include<iomanip>
using namespace std;
int n;
void qpl(int w)//全排列的函数
{
}
int main()
{
cin>>n;
qpl(1);
return 0;
}
全局定义一个n(表示最高位的数) 注意:一定要全局定义!
这里qpl(1)括号里的1表示数位是第一个数。
这道题我是用递归的方法做的,每次判断完一组就换下一组。
接下来我们来完善全排列函数里的代码:
#include<iostream>
#include<iomanip>
using namespace std;
int n,a[12],f[12];//a[12]用来存数,f[12]用来标记
void qpl(int w)
{
int i;
if(w==n+1)//每次输出n个数,所以要判定到n+1
{
for(i=1;i<=n;i++) cout<<setw(5)<<a[i];//setw是场宽代码,后面的括号里是空格个数
cout<<endl;
}
for(i=1;i<=n;i++)
{
if(f[i]==0)//用来判断当前数用没用过
{
f[i]=1;
a[w]=i;
qpl(w+1);
f[i]=0;
a[w]=0;
}
}
}
上面代码可以保证输出不重复。
组合后就是下面的代码:
AC代码:
#include<iostream>
#include<iomanip>
using namespace std;
int n,a[12],f[12];
void qpl(int w)
{
int i;
if(w==n+1)
{
for(i=1;i<=n;i++) cout<<setw(5)<<a[i];
cout<<endl;
}
for(i=1;i<=n;i++)
{
if(f[i]==0)
{
f[i]=1;
a[w]=i;
qpl(w+1);
f[i]=0;
a[w]=0;
}
}
}
int main()
{
cin>>n;
qpl(1);
return 0;
}