习题2.8 输出全排列 (20 分)
请编写程序输出前n个正整数的全排列(n<10),并通过9个测试用例(即n从1到9)观察n逐步增大时程序的运行时间。
输入格式:
输入给出正整数n(<10)。
输出格式:
输出1到n的全排列。每种排列占一行,数字间无空格。排列的输出顺序为字典序,即序列a1?,a2?,?,an?排在序列b1?,b2?,?,bn?之前,如果存在k使得a1?=b1?,?,ak?=bk??并且?ak+1?<bk+1?。
输入样例:
3
结尾无空行
输出样例:
123
132
213
231
312
321
结尾无空行
思路:按照从小到大依次排列好。如果最后一个位置全部数字都用了,则返回上一个位置把数字取出,上一个位置的数字+1,然后重新进入下一个位置搜索没有用过的数字再从小到大排列。当然我的描述非常糟糕,看代码的话会非常的简洁明了
#include <stdio.h>
int a[10],b[10];//需要两数组 a代表位置,b代表可放置的数字
int n;
void fun(int j);
int main(void){
scanf("%d",&n);
fun(1);
return 0;
}
void fun(int j){
int i;
if(j==n+1) {//爆表了说明前面放满了数字——所有数字已经用出,就直接输出
for(i=1;i<=n;i++) printf("%d",a[i]);
printf("\n"); return;
}
for(i=1;i<=n;i++){//没有爆表,说明还存在数字没用,
if(b[i]==0){//判断哪个数字没用,没用过的数字为b[i]对应值为0
a[j]=i;//把数字放入j位置
b[i]=1;//对应数字用出,变为1标记已使用
fun(j+1);//深度到下一个位置
b[i]=0;//如果被返回时,则说明这给数字需要重新放置故取消标记值
}
}
return;//返回上个函数
}
|