HDU1027-Ignatius and the Princess II

http://acm.hdu.edu.cn/showproblem.php?pid=1027

这道题的意思是输出n个数全排列的第m个全排列。

很明显这道题用的是可以用深搜来解决这个问题,

我的思路是:寻找的是最优子结构,当全排列的第一个数确定之后,就第二个数就是n个数出去第一个数字的任意一个可能。

深搜是状态转移,从一个状态转换到另一个状态。

//hdu1027
#include <iostream>
#include <cstdio>
#include <cstring>
//注意为什么要用flag标记提前跳出循环。//回溯的原因!! 
/**
主要原因:
1.如果直接return的话就只是跳到上一层,
而flag是在回溯之前就定义好的,
所以当用flag标记直接调回的时候就不会仅仅返回第上一层,而是直接 逐层返回到第一层,然后结束。 
**/ 
using namespace std ;
int n,m,flag;
int a[1002],sum,vis[1002];
 void dfs(int k);
int main(){
    while(~scanf("%d%d",&n,&m)){
        memset(vis, 0, sizeof(vis));
        sum=flag=0;
        dfs(1);    
    }
    return 0;
} 
void dfs(int k){
    if(flag==1)return;//提前结束 
    if(k==n+1){
        sum++;
        if(sum==m){
            flag=1; 
            for(int i=1;i<n;i++){
                printf("%d ",a[i]);
            } 
            printf("%d\n",a[n]);
            return;//返回上一层 
        }
    }else{
        //这样做会多一个循环,运行超时,最好的办法就是记忆化 
//        for(int i=1;i<=n;i++){
//            int flag=1;
//            for(int j=1;j<k;j++){
//                if(i==a[j]){
//                    flag=0;
//                }
//            }
//            if(flag==1){
//                a[k]=i;
//                dfs(k+1);
//            }
//        }
        for(int i=1;i<=n;i++){
            if(!vis[i]){
                vis[i]=1;
                a[k]=i;
                dfs(k+1);
                vis[i]=0;//对于一个序列排列好之后,则都被访问过,所以为了下一次搜索需要清零 
            }
        }
    }
}

 

posted @ 2015-05-23 01:00  Yvettey  阅读(716)  评论(0编辑  收藏  举报