> Description
按字典顺序输出错位排列
> Input
n (n<=10)
> Output
字典顺序的错位排列
> Sample Input
4
> Sample Output
2 1 4 3
2 3 4 1
2 4 1 3
3 1 4 2
3 4 1 2
3 4 2 1
4 1 2 3
4 3 1 2
4 3 2 1
//数字间有一空格
> 解题思路
① 从后面向前找,直到找到一个顺序(由大到小)为止。
② 然后在a[j+1],a[j+2],…,a[n]中找出一个比a[j]大的最小的数。
③ 交换a[p]与a[j]。
④ 再将a[j+1],…,a[n]由小到大排序。
> 代码
#include<iostream>
#include<cstdio>
#include<algorithm>
using namespace std;
int s=1,a[11],n;
bool ooo()
{
for(int i=1;i<=n;i++)
if(a[i]==i) return false;
return true;
} //判断是否错位
void lil()
{
int t,p,j;
for(int i=1;i<=s;i++)
{
if(ooo()) //如果错位就输出
{
for(int x=1;x<=n;x++)
printf("%d ",a[x]);
printf("\n");
}
j=n; while(a[j]<a[j-1]) j--;
p=j; j--;
//从n开始搜索大到小的顺序,
//顺序的前一个字母为j。
for(int x=j+1;x<=n;x++)
if(a[x]>a[j]&&a[x]<a[p]) p=x;
//找出顺序中比j大的数中最小的数p。
t=a[j];a[j]=a[p];a[p]=t;//调换j,p的位置。
sort(a+j+1,a+n+1);//j+1到n从小到大排列。
}
}
int main()
{
scanf("%d",&n);
for(int i=1;i<=n;i++)
a[i]=i;
for(int i=1;i<=n;i++)
s*=i;
lil();
return 0;
}