• CF1036C Classy Numbers 题解


    CF1036C Classy Numbers 题解

    题目链接:CF1036C Classy Numbers

    题意:定义一个数字是“好数”,当且仅当它的十进制表示下有不超过 3 3 3个数字 1 ∼ 9 1 \sim 9 19

    举个例子: 4 , 200000 , 10203 4,200000,10203 4,200000,10203是“好数”,然而 4231 , 102306 , 7277420000 4231,102306,7277420000 4231,102306,7277420000不是

    给定 [ l , r ] [l,r] [l,r],问有多少个 x x x使得 l ≤ x ≤ r l \le x \le r lxr,且 x x x是“好数”

    一共有 T ( 1 ≤ T ≤ 1 0 4 ) T(1 \le T \le 10^{4}) T(1T104)组数据,对于每次的询问,输出一行一个整数表示答案

    1 ≤ l i ≤ r i ≤ 1 0 18 1 \le l_i \le r_i \le 10^{18} 1liri1018

    一般数位dp可以用来解决 ∑ i = l r f ( i ) \sum _{i=l}^{r} f(i) i=lrf(i) 的问题,

    其中 f ( i ) f(i) f(i) 为与 i i i 的数位有关的某个函数或判定式

    这题稍微变形了一下,那我们就理所当然地记录一下出现数字的情况

    f i , j f_{i,j} fi,j 表示满 i i i 位数,有 j j j 个非 0 0 0

    采用记忆化搜索,详见代码

    #include <iostream>
    #include <string>
    #include <vector>
    #include <algorithm>
    #include <cstdio>
    #include <cstdlib>
    #include <cstring>
    #include <cmath>
    #include <iomanip>
    using namespace std;
    #define int long long
    #define INF 0x3f3f3f3f3f3f3f3f
    #define N (int)()
    int num[25],f[25][5];
    // u表示当前位数,st表示当前的j,limit表示是否有高位限制
    int dfs(int u,int st,bool limit)
    {
        if(!u)return 1;
        if(!limit&&f[u][st]!=INF)
            return f[u][st]; // 记忆化
        int up=limit?num[u]:9,ans=0;
        for(int i=0; i<=up; i++)
        {
            if(!i)ans+=dfs(u-1,st,limit&&num[u]==i);
            else if(st!=3)ans+=dfs(u-1,st+1,limit&&num[u]==i);
        }
        if(!limit) f[u][st]=ans; // 只需记录无高位限制的
        return ans;
    }
    int solve(int x)
    {
        int len=0;
        while(x>0)
        {
            num[++len]=x%10;
            x/=10;
        }
        return dfs(len,0,1);
    }
    signed main()
    {
        ios::sync_with_stdio(0);
        cin.tie(0);cout.tie(0);
        // freopen("check.in","r",stdin);
        // freopen("check.out","w",stdout);
        memset(f,0x3f,sizeof(f));
        int Q;cin >> Q;
        while(Q--)
        {
            int l,r;
            cin >> l >> r;
            cout << solve(r)-solve(l-1) << '\n';
        }
        return 0;
    }
    
    • 1
    • 2
    • 3
    • 4
    • 5
    • 6
    • 7
    • 8
    • 9
    • 10
    • 11
    • 12
    • 13
    • 14
    • 15
    • 16
    • 17
    • 18
    • 19
    • 20
    • 21
    • 22
    • 23
    • 24
    • 25
    • 26
    • 27
    • 28
    • 29
    • 30
    • 31
    • 32
    • 33
    • 34
    • 35
    • 36
    • 37
    • 38
    • 39
    • 40
    • 41
    • 42
    • 43
    • 44
    • 45
    • 46
    • 47
    • 48
    • 49
    • 50
    • 51
    • 52
    • 53
    • 54
    • 55

    参考文献

    [1] https://www.luogu.com.cn/blog/rated/solution-cf1036c

    转载请说明出处

  • 相关阅读:
    解决WPF+Avalonia在openKylin系统下默认字体问题
    工作相关----《系统部署相关操作》
    EKF例程 matlab
    开发《俄罗斯方块》的意义
    微泡排气除污装置有哪几种叫法吗?
    Linux命令行操作:使用“more“命令进行分页显示
    [Vue]中数组的操作用法
    并发、并行和多线程关系
    Python中的依赖注入
    Git的常用操作命令有哪些
  • 原文地址:https://blog.csdn.net/qq_50332374/article/details/125622667