zoukankan      html  css  js  c++  java
  • hdu6468 dfs剪枝 or char数组 or 构造

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

    题意

    有一个序列,是1到n的一种排列,排列的顺序是字典序小的在前,那么第k个数字是什么?((1 leq n leq 10^6,1 leq k leq n,多组Tleq 100))

    题解1

    • 假如剪枝好的话,每次最多搜1e6,这样总共1e8,能过
    • dfs序>=k剪掉,num>n剪掉
    #include<bits/stdc++.h>
    
    using namespace std;
    int dfn,n,k,ans,T;
    void dfs(int num){
        if(dfn>=k)return;
        dfn++;
        //cout<<num<<" "<<dfn<<endl;
        if(dfn==k){ans=num;return;}
        int l=(!num?1:0);
        for(int i=l;i<=9;i++){
            if(num*10+i>n)return;  //continue就超时了
            dfs(num*10+i);
        }
    }
    int main(){
        cin>>T;
        while(T--){
            dfn=-1;
            scanf("%d%d",&n,&k);
            dfs(0);
            printf("%d
    ",ans);
        }
    }
    

    题解2

    https://www.twblogs.net/a/5c92e1f9bd9eee35cd6ba3b7/zh-cn

    • 预处理出所有字符串,排序,O(6nlog(6*n))
    #include <iostream>
    #include <algorithm>
    #include <cstdlib>
    #include <cmath>
    #include <cstring>
    #include <cstdio>
    #include <deque>
    #include <stack>
    using namespace std;
    typedef long long ll;
    const int MAX=1e6;
    const int MM=192600817;
    struct A
    {
        ll k;
        char  s[8];
    }a[MAX+1];
    bool cmp(struct A p,struct A q)
    {
        return strcmp(p.s,q.s)<0;
    }
    int main()
    {
        ll T,n,k,i,j;
        for(i=1;i<=MAX;i++)
        {
            a[i].k=i;
            ll t=i,e=0,m;
            while(t)
            {
                a[i].s[e]=(t%10)+'0';
                t/=10;
                e++;
            }
            for(j=0;j<e/2;j++)
            {
                char tt;
                tt=a[i].s[j];
                a[i].s[j]=a[i].s[e-j-1];
                a[i].s[e-j-1]=tt;
            }
        }
        sort(a+1,a+MAX+1,cmp);
        //cout<<a[1000].s<<endl;
        cin>>T;
        while(T--)
        {
            cin>>n>>k;
            i=1;
            for(i=1;i<=MAX;i++)
            {
                if(a[i].k>n)
                    continue;
                else
                    k--;
                if(k==0)
                    break;
            }
            cout<<a[i].k<<endl;
        }
        return 0;
    }
    

    题解3

    https://zeng1998.github.io/2019/03/16/hdu6468——zyb的面试/

    #include <iostream>
    #include <algorithm>
    using namespace std;
    typedef long long ll;
    ll solve(ll n,ll m){
        //考虑一颗完全10叉树,树的所有节点就是1-n,要求的就是前序遍历的第m个节点
        //m是可以走的步数
        ll i=1;
        m--;
        while(m!=0){
            //计算i到i+1的字典序中间相隔的个数
            ll s=i,e=i+1;
            ll num=0;
            //防止越界
            while(s<=n){
                //计算每一层相差的个数
                //n+1: 比如20-29其实是10个,而e就不用+1,因为e在这里表示30(40/50...)
                num+=min(n+1,e)-s;
                s*=10;
                e*=10;
            }
            if(m<num){
                //向下
                i*=10;
                //走一步
                m--;
            }else{
                //向右
                i++;
                //对前序遍历来说,走了num步
                m-=num;
            }
        }
        return i;
    }
    int t;
    ll n, m;
    int main() {
        scanf("%d",&t);
    	while (t--){
            scanf("%lld%lld",&n,&m);
            printf("%lld
    ",solve(n,m));
        }
    	return 0;
    }
    
  • 相关阅读:
    Java++:一文搞懂分布式锁及其业务场景
    Get MSN ADS
    删除废弃的全文索引
    门户网页分页(pagination Style)
    SQL Server 无法查看属性
    FileUpload Control In ASP.NET2.0
    根据IP和掩码获取主机IP区域
    IIS 使用域用户
    Get MSN ADS by xmlHttpRequest
    二进制时钟
  • 原文地址:https://www.cnblogs.com/VIrtu0s0/p/10817177.html
Copyright © 2011-2022 走看看