HDOJ-6628(dfs+第k字典序最小差异序列)

permutation 1

HDOJ-6628

  • 这题使用的暴力深搜,在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;
}
posted @ 2019-08-08 17:37  Garrett_Wale  阅读(173)  评论(0编辑  收藏  举报