请编写程序输出前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
分析:
此题有两种分析法:第一种:将要n个要排列的整数看成一个整数,每次加9然后判断是否符合题目要求,成立就输出,例如:123到132,需要123加9;132到213,需要132加9个9……但是本人发现有很多无效数也要经过判断,因此最后一个测试点要超时(本地测试用时33秒),希望有大神能帮我解决这个问题,谢谢!
第二种:将n个数放入长度为n的数组,从左到右,数组中的第一个元素循环一次(循环条件范围是1到n),然后判断是否与前面的元素值一样,如果一样就再做一次循环,如果不一样就将下一个元素进行同样操作;如果超出循环条件范围,则先将当前位置下的元素值置为零,同时向左退一格,进行同样的操作……当最后一个元素经过处理后,就输出当前数组中的所有元素值。以输入样例为例,因为输入是3,所以先产生一个长度为3的数组,第零号元素先产生1,因为该元素是第一个元素,前面没有元素,且1在1到3之间,所以对下一个元素(即第1号元素)进行处理,第一号元素先产生1,因为1与第零号元素重复,所以在循环一次变为2,此时符合条件……当第2号元素产生3后,立即输出有元素(即123),因为第2号元素为最大,不能再循环了,所以向左退一格,此时该位置下元素变为3,符合条件……当321输出后,程序结束(此算法最后一个测试点用时500毫秒)。
#include<stdio.h>
int main(void)
{
int a[9]={0};
int i=0;
int j=0;
int k=0;
int n=0;
int temp=0;
int count=0;
int sum=1;
scanf("%d",&n);
for(i=1;i<=n;++i)
sum*=i; //模拟n!运算
i=0;
for(i=0;i<n;++i)
{
up:
for(temp=a[i]+1;temp<=n;)
{
for(k=0;k<i;++k)
if(a[k]==temp)
goto end;
a[i]=temp;
break;
end:
++temp;
}
if(temp>n)
{
a[i]=0;
i=i-2;
}
if(i==n-1)
{
for(j=0;j<n;++j)
if(j==n-1)
printf("%d\n",a[j]);
else
printf("%d",a[j]);
++count;
if(count==sum)
break;
goto up;
}
}
return 0;
}
如果有误请告知作者,感激不尽!