我是靠谱客的博主 温柔西装,最近开发中收集的这篇文章主要介绍BZOJ 1833 [ZJOI2010]count 数字计数(数位dp),觉得挺不错的,现在分享给大家,希望可以做个参考。

概述

题目链接:[kuangbin带你飞]专题十五 数位DP D - Bomb

题意

输入n,m,求n~m范围内的所有数字中,分别输出0~9出现的总数是多少。

思路

和 POJ 3286 How many 0’s? (数位dp)的思路基本是一样的,只是略有区别。
0和1~9要分开处理,是因为前缀0的问题。因为当某一位取0时,前面部分的数是不能为0的,而取1~9是可以前面为0的。

代码

#include <iostream>
#include <algorithm>
#include <cstring>
#include <cstdio>
#include <cstdlib>
#include <vector>
#include <cmath>
#include <map>

using namespace std;

#define LL long long
LL p[20];
LL ans[10] = {};

void init()
{
    p[0] = 1;
    for(int i=1; i<18; i++)
        p[i] = p[i-1]*10;
}

void solve(LL x, int f)
{
    if(x == -1)
    {
        ans[0]++;
        return;
    }
    for(int k=1; k<10; k++)
    {
        for(int i=1; ; i++)
        {
            LL l = x/p[i];
            LL r = x%p[i-1];
            LL now = x%p[i]/p[i-1];
            if(now > k)
                ans[k] += (l+1)*p[i-1]*f;
            else if(now == k)
                ans[k] += (l*p[i-1]+r+1)*f;
            else
                ans[k] += l*p[i-1]*f;
            if(p[i] > x)
                break;
        }
    }
    for(int i=1; ; i++)
    {
        LL l = x/p[i];
        LL r = x%p[i-1];
        LL now = x%p[i]/p[i-1];
        if(now > 0)
            ans[0] += l*p[i-1]*f;
        else
            ans[0] += ((l-1)*p[i-1]+r+1)*f;
        if(p[i] > x)
            break;
    }
}

int main()
{
    LL n, m;
    init();
    cin>>n>>m;
    solve(m, 1);
    solve(n-1, -1);
    for(int i=0; i<9; i++)
        printf("%lld ", ans[i]);
    printf("%lldn", ans[9]);
    return 0;
}

最后

以上就是温柔西装为你收集整理的BZOJ 1833 [ZJOI2010]count 数字计数(数位dp)的全部内容,希望文章能够帮你解决BZOJ 1833 [ZJOI2010]count 数字计数(数位dp)所遇到的程序开发问题。

如果觉得靠谱客网站的内容还不错,欢迎将靠谱客网站推荐给程序员好友。

本图文内容来源于网友提供,作为学习参考使用,或来自网络收集整理,版权属于原作者所有。
点赞(66)

评论列表共有 0 条评论

立即
投稿
返回
顶部