一.题目
题目描述
按照字典序输出自然数 11 到 nn 所有不重复的排列,即 nn 的全排列,要求所产生的任一数字序列中不允许出现重复的数字。
输入格式
一个整数 nn。
输出格式
由 1∼n1∼n 组成的所有不重复的数字序列,每行一个序列。
每个数字保留 55 个场宽。
二.代码
#include<bits/stdc++.h>
using namespace std;
//定义swap函数
//传递的参数是变量的引用,会改变变量的值
void swap(int &a,int &b)
{
int temp=a;
a=b;
b=temp;
}
void Perm(int list[],int k,int m)
{
if(k==m)
{
for(int i=0;i<=m;i++)
{
cout<<setw(5)<<list[i];
}
cout<<endl;
}
else{
for(int i=k;i<=m;i++)
{
//保证全排列的顺序
//sort函数的第二个参数是一个开区间,不包含m+1
sort(list+k,list+m+1);
swap(list[i],list[k]);
Perm(list,k+1,m);
swap(list[i],list[k]);
}
}
}
int main()
{
int n;
cin>>n;
int a[n];
for(int i=0;i<n;i++)
{
a[i]=i+1;
}
Perm(a,0,n-1);
return 0;
}
三.遇到的困难——全排列的顺序
输入3的时候,3的全排列结果比较正确。
但是我输入4的时候,4的全排列结果不理想,全部WA,仔细一看是全排列顺序出了问题。
正常情况下应该是:
1 2 3 4
1 2 4 3
1 3 2 4
1 3 4 2
1 4 2 3
1 4 3 2
但我的代码的结果是:
1 2 3 4
1 2 4 3
1 3 2 4
1 3 4 2
1 4 3 2
1 4 2 3
后来参考了别人的代码,发现在每次递归前加上一段部分排列的代码段即可:
//保证全排列的顺序
//sort函数的第二个参数是一个开区间,不包含m+1
sort(list+k,list+m+1);
但需要注意的是,sort函数的第二个参数不被包含,所以为sort(list+k,list+m+1);,表示对list[k]到list[m+1]进行交换。