zoukankan      html  css  js  c++  java
  • [P2602] [ZJOI2010]数字计数(数位dp)

    原题

    题目描述

    给定两个正整数 (a)(b),求在 ([a,b]) 中的所有整数中,每个数码(digit)各出现了多少次。

    输入格式

    仅包含一行两个整数 (a,b),含义如上所述。

    输出格式

    包含一行十个整数,分别表示 (0∼9)([a,b])中出现了多少次。

    输入输出样例

    输入 #1

    1 99
    

    输出 #1

    9 20 20 20 20 20 20 20 20 20
    

    说明/提示

    数据规模与约定

    • 对于 (30\%) 的数据,保证 (a≤b≤10^6)
    • 对于 (100\%) 的数据,保证 (1≤a≤b≤10^{12})

    思路

    数位dp套模板,注意前导零。

    #include <algorithm>
    #include <cmath>
    #include <cstdio>
    #include <cstring>
    #include <list>
    #include <map>
    #include <iostream>
    #include <iomanip>
    #include <queue>
    #include <set>
    #include <stack>
    #include <string>
    #include <unordered_map>
    #include <vector>
    #define LL long long
    #define inf 0x3f3f3f3f
    #define INF 0x3f3f3f3f3f3f
    #define PI 3.1415926535898
    #define F first
    #define S second
    #define endl '
    '
    #define lson rt << 1
    #define rson rt << 1 | 1
    #define lowbit(x) (x & (-x))
    #define f(x, y, z) for (int x = (y), __ = (z); x < __; ++x)
    #define _rep(i, a, b) for (int i = (a); i <= (b); ++i)
    #define _per(i, a, b) for (int i = (a); i >= (b); --i)
    using namespace std;
    LL dp[20][20];
    LL l, r;
    int a[20], tar;
    inline LL dfs(int pos, int cnt, bool lead, bool limit)
    {
        if (pos == -1)
            return cnt;
        if (!limit && !lead && dp[pos][cnt] != -1)
            return dp[pos][cnt];
        int up = limit ? a[pos] : 9;
        LL ans = 0;
        for (int i = 0; i <= up; i++)
        {
            ans += dfs(pos - 1, cnt + ((!lead || i) && (i == tar)), lead && (i == 0), limit && (i == a[pos]));
        }
        if (!limit && !lead)
            dp[pos][cnt] = ans;
        return ans;
    }
    
    inline LL solve(LL x, int num)
    {
        memset(dp, -1, sizeof(dp));
        tar = num;
        int pos = 0;
        while (x)
        {
            a[pos++] = x % 10;
            x /= 10;
        }
        a[pos] = 0;
        return dfs(pos - 1, 0, true, true);
    }
    int main()
    {
        ios::sync_with_stdio(false);
        cin.tie(0);
        cin >> l >> r;
        _rep(i, 0, 9)
        {
            cout << solve(r, i) - solve(l - 1, i) << " ";
        }
    }
    
  • 相关阅读:
    [原]实例-简单设计&精简代码&复用代码
    [原创]实例-少用单例及降低耦合
    c#实现数据集合转换为csv文本
    [转]SqlServer索引的原理与应用
    [转]AngularJS:何时应该使用Directive、Controller、Service?
    [转]AngularJS移动开发中的坑汇总
    [转]Hibernate对象的三种状态
    [转]AngularJS Cookies Example
    [转]LESS CSS 框架简介
    [转]为ReportViewer导出的PDF文档加上水印
  • 原文地址:https://www.cnblogs.com/hfcdyp/p/14136847.html
Copyright © 2011-2022 走看看