题目
列出所有数字1到数字n的连续自然数的排列,要求所产生的任一数字序列中不允许出现得复数字。
输入
一个数,n
输出
所有的排列,一行一个
思路
生成排列:
① 从后面向前找,直到找到一个顺序(由大到小)为止。
算法为:j=n;
while (a[j]<a[j-1]) j--;
② 然后在a[j],a[j+1],…,a[n]中找出一个比a[j-1]大的最小的数,算法为:
p=j;
for(i=j+1;i<=r;i++)
if (a[i]>a[j-1]&&a[i]<a[p]) p=i;
③ 交换a[p]与a[j-1]
④ 再将a[j],a[j+1],…,a[n]由小到大排序
代码
#include<cstdio>
#include<algorithm>
using namespace std;
int n,a[11],j=1,k,p,l;
int main(){
scanf("%d",&n);
for(int i=1;i<=n;i++)
a[i]=i; //生成初始序列
for(int i=2;i<=n;i++) j=j*i; //算出有多少排列
for(int i=1;i<=j;i++){
for(k=1;k<=n;k++)
printf("%d ",a[k]); //输出第i种排列
printf("\n");
if(i==j) break;//后面生成新排列
for(k=n-1;k>=1;k--) //刚刚说的
if(a[k]<a[k+1]) break;
p=k+1;
for(l=k+1;l<=n;l++)
if(a[l]>a[k]&&a[l]<a[p]) p=l;
l=a[p];a[p]=a[k];a[k]=l;
sort(a+1+k,a+1+n);
}
return 0;
}