• hdu6468(记忆化搜索)


    zyb的面试

    Time Limit: 2000/1000 MS (Java/Others)    Memory Limit: 65536/65536 K (Java/Others)
    Total Submission(s): 695    Accepted Submission(s): 254


    Problem Description
    今天zyb参加一场面试,面试官听说zyb是ACMer之后立马抛出了一道算法题给zyb:
    有一个序列,是1到n的一种排列,排列的顺序是字典序小的在前,那么第k个数字是什么?
    例如n=15,k=7, 排列顺序为1, 10, 11, 12, 13, 14, 15, 2, 3, 4, 5, 6, 7, 8, 9;那么第7个数字就是15.
    那么,如果你处在zyb的场景下,你能解决这个问题吗?
     
    Input
    T组样例(T<=100)
    两个整数n和k(1<=n<=1e6,1<=k<=n),n和k代表的含义如上文
     
    Output
    输出1-n之中字典序第k小的数字
     
    Sample Input
    1 15 7
     
    Sample Output
    15
     
    Source
     
     
    思路:见代码
    #include<cstdio>
    #include<algorithm>
    using namespace std;
    int dis[10];//把n分解 
    int cnt,len,ans,k,n;
    bool lg1;
    int ws[10];//判断每一位都取值时最终的值是否可能超过n 
    int dp[10];//取到底的记忆化 
    int les[10];//不取到底的记忆化(当前值已经大于n并且还没到底,就返回了) 
    int dfs(int pos,int sum,int po){//sum*po为当前值,ws[pos]为上界,
        if(sum*po<ws[pos]&&dp[pos]!=-1&&(cnt+dp[pos]<k)){//当找的范围还在k内 
            cnt+=dp[pos];//当当前值小于上界时,就记忆化每一位都取的情况 
            return dp[pos];
        }
        else if(sum*po>ws[pos]&&les[pos]!=-1&&(cnt+les[pos]<k)){
            cnt+=les[pos];//当当前值大于上界,就记忆化至少有一位不选的情况(当至少有一位没取时可以保证 
            return les[pos];//最后得到的值一定小于n 
        }
        int sum2=cnt;
        int sum1=0;
        if(sum<=n){//当当前值满足条件时 
            sum1++;
            cnt++;
            if(cnt==k){
                ans=sum;
                lg1=false;
                return 0;
            }
        }
        else
        return 0;
        if(pos==0)
        return sum1;
        for(int i=0;i<=9&&lg1;i++){//往下走 
            sum1+=dfs(pos-1,sum*10+i,po/10);
        }
        //printf("%d %d
    ",sum*po,ws[pos]);
        if(sum*po<ws[pos])//当没有到上界 
        dp[pos]=sum1;
        else if(sum*po>ws[pos])//当到上界 
        les[pos]=cnt-sum2;
        return sum1;
    }
    int main(){
        int t;
        scanf("%d",&t);
        while(t--){
            cnt=0;
            scanf("%d%d",&n,&k);
            len=0;
            fill(dp,dp+8,-1);
            fill(les,les+8,-1);
            int m=n;
            int po=1;
            while(m){
                po*=10;
                dis[++len]=m%10;
                m/=10;
            }
            int r=1;
            int summ=0;
            for(int i=1;i<len;i++){
                summ+=dis[i]*r;
                ws[i]=n-summ;
                r*=10;            
            }
            lg1=true;
            for(int i=1;i<=9&&lg1;i++){
                dfs(len-1,i,po/10);
            }    
            printf("%d
    ",ans);
        }
        return 0;
    }
  • 相关阅读:
    关于prototype学习
    java io 从文件的读取和输入
    java 匿名内部类
    动手做个 AI 机器人,帮我回消息!
    几个高效做事的法则,让你的一天有 25 小时
    爆肝一个月,我做了个免费的面试刷题网
    Log4j 被曝核弹级漏洞,开发者炸锅了!
    几个超火的编程网站,别错过!
    Java 处理表格,真的很爽!
    c++智能指针转化:static_pointer_cast、dynamic_pointer_cast、const_pointer_cast、reinterpret_pointer_cast
  • 原文地址:https://www.cnblogs.com/cglongge/p/10852758.html
Copyright © 2020-2023  润新知