题目大意:给出n和m。对1到n进行全排列,按照字典序输出第m个排列的序列。
解题思路:开始以为就是一个全排的题,直接就dfs递归写了个,提交TLE,才发现这样会T。然后查了下,发现这个题有好几种写法,最简单易用的是STL的next_permutation,直接一下就A了。想想STL之所以这么快肯定有什么不一样的实现方法,而递归的写法也可以进行改进,现在主要是没时间,因此,将两个code都贴出来,后边再来完善。详见code。
题目来源:http://acm.hdu.edu.cn/showproblem.php?pid=1027
STL code:
#include <iostream>
#include <cstdio>
#include <algorithm>
using namespace std;
const int MAXN = 10000;
int n,m;
int num[MAXN];
int main(){
while(scanf("%d%d",&n,&m)!=EOF){
for(int i=0;i<n;i++)
num[i]=i+1;
while(--m) //获取第m次排列
next_permutation(num,num+n);
for(int i=0;i<n-1;i++)
printf("%d ",num[i]);
printf("%d\n",num[n-1]);
}
return 0;
}
dfs+递归 code( TLE,待修改):
#include <iostream>
#include <cstdio>
#include <cstring>
using namespace std;
const int MAXN = 10000;
int n,m,tmp;
int rcd[MAXN],num[MAXN],used[MAXN];
void full_permutation(int l){
if(l==n){
tmp++;
if(tmp==m){
for(int i=0;i<n;i++){
printf("%d",rcd[i]);
if(i<n) printf(" ");
}
printf("\n");
return ;
}
}
for(int i=0;i<n;i++)
if(!used[i]){
used[i]=1;
rcd[l]=num[i];
full_permutation(l+1);
used[i]=0;
}
}
int main(){
while(scanf("%d%d",&n,&m)!=EOF){
memset(used,0,sizeof(used));
for(int i=0;i<n;i++)
num[i]=i+1;
tmp=0;
full_permutation(0);
}
return 0;
}