zoukankan      html  css  js  c++  java
  • 2020 ICPC 台北区域赛 K

    题意:

    一个数如果没有任何两位的数字是相同的,则该数称为B数,有两种询问:

    • 问[a,b]区间有多少个B数(在10/16进制下)
    • 问第k个B数是什么(在10/16进制下)

    思路:

    显然第一类问题可以用数位DP求解,第二类问题就是在数位dp外面套个二分就可以求解。由于输入的数都是unsigned long long,有一些细节需要注意,比如边界特判等。二分的时候采用左开右闭,因为如果[0,a]存在k个B数,那么此时二分的右边界就是a,且可以取到。

    代码:

    #include <bits/stdc++.h>
    using namespace std;
    typedef unsigned long long ull;
    inline bool test(int x,int y){
        if((x>>y)&1)return 1;
        else return 0;
    }
    char domin;
    int a[21],len;
    ull dp[21][1<<16|1][2][2];
    ull dfs(int pos,int limit,int lead,int st,int base){
        if(pos==0) return !lead;
        if(!limit && dp[pos][st][lead][base==10?0:1]!=-1)
            return dp[pos][st][lead][base==10?0:1];
        ull ans=0;
        int maxx=limit?a[pos]:base-1;
        for(int i=0;i<=maxx;i++){
            if(!test(st,i)){
                ans+=dfs(pos-1,limit&&i==maxx,lead&&i==0,(lead&&i==0)?0:st|(1<<i),base);
            }
        }
        if(!limit) dp[pos][st][lead][base==10?0:1]=ans;
        return ans;
    }
    ull solve1(ull x){
        len=0;
        int base=domin=='d'?10:16;
        while(x){
            a[++len]=x%base;
            x/=base;
        }
        return dfs(len,1,1,0,base);
    }
    void input(ull &a){
         if(domin=='d')
            scanf("%llu",&a);
         else{
            a=0;
            char ch=getchar();
            while(!(ch>='0' && ch<='9')&&!(ch>='a' && ch<='f')) ch=getchar();
            while( (ch>='0' && ch<='9')||(ch>='a' && ch<='f') ){
                a=a*16;
                if(ch>='a')
                    a+=10+ch-'a';
                else
                    a+=ch-'0';
                ch=getchar();
            }
         }
    }
    void print(ull a){
        if(a==0){
            puts("0");return;
        }
        if(domin=='d'){//10
            printf("%llu
    ",a);return;
        }
        //16
        vector<int>ans;
        while(a){
            ans.push_back(a%16);
            a/=16;
        }
        for(int i=ans.size()-1;i>=0;i--){
            if(ans[i]>=10)
                printf("%c",'a'+ans[i]-10);
            else
                printf("%d",ans[i]);
        }
        puts("");
    }
    int main () {
        domin='h';
        memset(dp,-1,sizeof dp);
        int T;
        scanf("%d",&T);
        while(T--){
            ull a,b,i;
            scanf(" %c",&domin);
            int typ;scanf("%d",&typ);
            if(typ==0){
                input(a);
                input(b);
                ull ans=solve1(b);
                if(a==0)ans++;
                else{
                    ans-=solve1(a-1);
                }
                print(ans);
            }
            else{
                input(i);
                if(i<9){
                    printf("%llu
    ",i-1);
                    continue;
                }
                ull l=0,r=0;r--;
                if(solve1(r)<i-1){
                    puts("-");
                    continue;
                }
                while(r-l>1){//zkyb
                    ull mid=(r>>1)+(l>>1);
                    if((r&1)&&(l&1))mid++;
                    if(solve1(mid)<i-1)
                        l=mid;
                    else
                        r=mid;
                }
                print(r);
            }
        }
    }
    
  • 相关阅读:
    Python 爬虫js加密破解(一) 爬取今日头条as cp 算法 解密
    Python 爬虫实例(2)—— 爬取今日头条
    Python 爬虫实例(1)—— 爬取百度图片
    python 操作redis之——HyperLogLog (八)
    python 操作redis之——有序集合(sorted set) (七)
    Python操作redis系列之 列表(list) (五)
    Python操作redis系列以 哈希(Hash)命令详解(四)
    Python操作redis字符串(String)详解 (三)
    How to Install MySQL on CentOS 7
    Linux SSH远程文件/目录 传输
  • 原文地址:https://www.cnblogs.com/ucprer/p/14000652.html
Copyright © 2011-2022 走看看