• SP3928 MDIGITS - Counting Digits 题解


    SP3928 MDIGITS - Counting Digits 题解

    题目链接:SP3928 MDIGITS - Counting Digits

    题意

    给定两个整数 a a a b b b,求 a a a b b b 之间的所有数字中 0 0 0 ~ 9 9 9 出现次数。

    例如, a a a = 1024 1024 1024 b b b = 1032 1032 1032,则 a a a b b b 之间共有 9 9 9 个数如下:

    1024 1025 1026 1027 1028 1029 1030 1031 1032

    其中 0 出现 10 10 10 次,1 出现 10 10 10 次,2 出现 7 7 7 次,3 出现 3 3 3 次等等……

    数位dp的基础题

    f i f_i fi 表示满 i i i 位数字(包括前导零),每种数字的出现次数
    f 1 = 1 f i = f i − 1 × 10 + 1 0 i − 1 f_1 = 1 \\f_i = f_{i-1} \times 10 + 10^{i-1} f1=1fi=fi1×10+10i1
    其中 f i − 1 × 10 f_{i-1}\times 10 fi1×10 i − 1 i-1 i1 位及以下位的贡献

    例如 7000 ∼ 7999 ,   8000 ∼ 8999 \tt{7000\sim7999,~8000\sim8999} 70007999, 80008999

    显然 000 ∼ 999 \tt{000\sim999} 000999出现了 10 10 10

    1 0 i − 1 10^{i-1} 10i1 是第 i i i 位的贡献,比如 9000 ∼ 9999 \tt{9000 \sim 9999} 90009999 ,第 4 4 4 位的 9 \tt{9} 9 出现了 1 0 3 10^3 103

    然后我们再考虑怎么获得答案

    首先 [ l , r ] [l,r] [l,r] 可以拆分为 [ 0 , l − 1 ] ,   [ 0 , r ] [0,l-1],~[0,r] [0,l1], [0,r] 两个询问(基本的容斥)

    然后考虑一个数 A B C ‾ \tt{\overline{ABC}} ABC ,不难发现, 0 \tt{0} 0 A 00 ‾ \tt{\overline{A00}} A00 每个非最高位数都出现了 A \tt{A} A × f 2 \times f_2 ×f2

    而最高位 0 ∼ A − 1 \tt{0\sim A-1} 0A1 都各出现了 1 0 2 10^2 102

    注:这里 0 \tt 0 0 是前导零,所以其实不会算进去,这里只是为了方便分析

    那么 A \tt{A} A 呢?不难发现它出现了 B C ‾ + 1 \tt{\overline{BC}+1} BC+1

    对于 B \tt{B} B ,同样的处理方式。

    怎么一股机翻的味道

    然后我们就搞定这道题了

    时间复杂度 O ( Q l b ) O(Qlb) O(Qlb)

    其中 l l l 表示最大位数, b b b 表示进制,这题里为 10 10 10

    代码:(非dfs写法)

    #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 a,b,mi[25],cnt1[25],cnt2[25],num[25],f[25];
    void clear()
    {
        memset(cnt1,0,sizeof(cnt1));
        memset(cnt2,0,sizeof(cnt2));
    }
    void solve(int x,int *cnt)
    {
        int len=0;
        memset(num,0,sizeof(num));
        while(x)
        {
            num[++len]=x%10;
            x/=10;
        }
        for(int i=len; i>=1; i--)
        {
            for(int j=0; j<=9; j++)
                cnt[j]+=f[i-1]*num[i];
            for(int j=0; j<num[i]; j++)
                cnt[j]+=mi[i-1];
            int res=0;
            for(int j=i-1; j>=1; j--)
            {
                res = res * 10 + num[j];
            }
            cnt[num[i]]+=res+1;
            cnt[0]-=mi[i-1];
        }
    }
    signed main()
    {
        ios::sync_with_stdio(0);
        cin.tie(0);cout.tie(0);
        // freopen("check.in","r",stdin);
        // freopen("check.out","w",stdout);
        mi[0]=1;
        for(int i=1; i<=18; i++)
        {
            f[i]=f[i-1]*10+mi[i-1];
            mi[i]=10*mi[i-1];
        }
        while(cin >> a >> b)
        {
            if(!a&&!b)return 0;
            if(a>b)swap(a,b);
            clear();
            solve(a-1,cnt1);solve(b,cnt2);
            for(int i=0; i<=9; i++)
                cout << cnt2[i]-cnt1[i] << " \n"[i==9];
        }
        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
    • 56
    • 57
    • 58
    • 59
    • 60
    • 61
    • 62
    • 63
    • 64
    • 65
    • 66
    • 67

    转载请说明出处

  • 相关阅读:
    【Redis】Redis与SSM整合&Redis注解式缓存&Redis解决缓存问题
    Odoo:行业领先的免费开源财务管理解决方案
    【mysql 事件自启动】mysql重启开启事件
    构建嵌入式Linux操作系统 Linux操作系统的介绍
    如何实施企业采购战略?
    .NET6接入Skywalking链路追踪完整流程
    数学建模学习(99):多目标寻优 非支配排序遗传算法NSGA III
    LeetCode --- 1431. Kids With the Greatest Number of Candies 解题报告
    批处理中的%~语法
    【阅读笔记】《Effective C++》
  • 原文地址:https://blog.csdn.net/qq_50332374/article/details/125615845