permutation 1
- 这题使用的暴力深搜,在dfs里面直接从最小的差异开始枚举
- 注意这里的pre记录前一个数,并且最后答案需要减去排列中最小的数再加一
- 这里有一个技巧关于求第k小的问题,就是在dfs里面只要找到满足的长度为n的排列,k就减一,这样当k为0时的排列就是字典序第k小的了。
#include<iostream>
#include<cstdio>
#include<algorithm>
#include<cstring>
#include<string>
using namespace std;
int n,k;
int a[22];
bool vis[100];
bool dfs(int num,int pre,int mins,int maxs){
if(num==n){
if(k==1){
for(int i=0;i<n;i++){
cout<<a[i]-mins+1;
if(i==n-1)
cout<<endl;
else cout<<" ";
}
return 1;
}
k--;
return 0;
}
for(int i=1-n;i<n;i++){
int now=pre+i;
if(!vis[now]){
vis[now]=1;
if(max(maxs,now)-min(mins,now)<n){
a[num]=now;
if(dfs(num+1,now,min(mins,now),max(maxs,now))){
vis[now]=0;
return 1;
}
}
vis[now]=0;
}
}
return 0;
}
int main(){
int t;
cin>>t;
while(t--){
memset(vis,0,sizeof(vis));
cin>>n>>k;
vis[n]=1;
a[0]=n;
dfs(1,n,n,n);
vis[n]=0;
}
return 0;
}