• 51Nod 1042 数字0-9的数量(数位DP)


    题意:

    求[l,r]中数字0-9分别出现的次数,11算两次1

    思路:

    数位dp题解好难写,直接贴代码吧

    dp[i]表示[0, 10^i-1]中出现j的次数(按i位补全前导0,显然0-9出现的次数是相同的)

    最后再减去每一位出现的前导零即可

    代码:

    #include<iostream>
    #include<cstdio>
    #include<algorithm>
    #include<cmath>
    #include<cstring>
    #include<string>
    #include<stack>
    #include<queue>
    #include<deque>
    #include<set>
    #include<vector>
    #include<map>
    #include<functional>
        
    #define fst first
    #define sc second
    #define pb push_back
    #define mem(a,b) memset(a,b,sizeof(a))
    #define lson l,mid,root<<1
    #define rson mid+1,r,root<<1|1
    #define lc root<<1
    #define rc root<<1|1
    #define lowbit(x) ((x)&(-x)) 
    
    using namespace std;
    
    typedef double db;
    typedef long double ldb;
    typedef long long ll;
    typedef long long LL;
    typedef unsigned long long ull;
    typedef pair<int,int> PI;
    typedef pair<ll,ll> PLL;
    
    const db eps = 1e-6;
    const int mod = 998244353;
    const int maxn = 2e5+100;
    const int maxm = 2e6+100;
    const int inf = 0x3f3f3f3f;
    const db pi = acos(-1.0);
    
    ll n;
    ll dp[maxn];
    ll po[maxn];
    vector<ll> sv(ll n){
        ll len = 0;
        vector<ll>ans(10);
        for(int i = 0; i < 10; i++)ans[i] = 0;
        ll tmp = 0;
        ll x = n;
        while(n){
            ll d = n%10;
            n/=10;
            len++;
            for(int i = 0; i < 10; i++){
                if(d > i){
                    ans[i] += po[len-1] + d*dp[len-1];
                }
                else if(d==i){
                    ans[i] += d*dp[len-1]+tmp+1;
                }
                else{
                    ans[i] += d*dp[len-1]; 
                }
            }
            tmp += d*po[len-1];
        }
        ll m = 1;
        while(x){
            ans[0]-=m;
            m*=10;
            x/=10;
        }
        return ans;
    }
    
    int main() {
        //dp[0] = 0;
        ll tmp = 1;
        po[0] = 1;
        for(int i = 1; i <= 18; i++){
            po[i] = 10*po[i-1];
            dp[i] = dp[i-1]*10 + po[i-1];
        }
        ll l, r;
        scanf("%lld %lld", &l,&r);
        //scanf("%lld",&r);
        vector<ll>v1(10),v2(10);
        v1=sv(l-1);
        v2=sv(r);
        for(int i = 0; i < 10; i++){
            printf("%lld
    ",v2[i]-v1[i]);
        }
        return 0;
    
    }
    /*
    15542
    
     */
  • 相关阅读:
    APUE学习笔记:第四章 文件和目录
    APUE学习笔记:第三章 文件I/O
    APUE学习笔记:第二章 UNIX标准化及实现
    APUE学习笔记:第一章 UNUX基础知识
    《数据库系统概念》学习笔记2
    go语言下载地址
    Centos7 编译 android4.4
    剑侠情缘新进展
    ubuntu server 14.04手动安装svn
    ubuntu server 14.04 lts显示乱码的问题
  • 原文地址:https://www.cnblogs.com/wrjlinkkkkkk/p/10519565.html
Copyright © 2020-2023  润新知