51nod 1042 数字0-9的数量 (数位dp、dfs、前导0)

1042 数字0-9的数量

基准时间限制:1 秒 空间限制:131072 KB 分值: 10 难度:2级算法题

收藏

关注

取消关注

给出一段区间a-b,统计这个区间内0-9出现的次数。

比如 10-19,1出现11次(10,11,12,13,14,15,16,17,18,19,其中11包括2个1),其余数字各出现1次。

Input

两个数a,b(1 <= a <= b <= 10^18)

Output

输出共10行,分别是0-9出现的次数

Input示例

10 19

Output示例

1
11
1
1
1
1
1
1
1
1

终于过了,前导零太烦了。
#include <iostream>
#include <cstring>
using namespace std;
typedef long long ll;
ll ten[20]={1},a[20],dp[20];
void init()
{
    for(ll i=1;i<20;i++)
        ten[i]=ten[i-1]*10;
}
ll dfs(ll pos,ll num,ll lead,ll limit,ll who)
{
    if(pos==-1) return num;
    if(!limit&&dp[pos]!=-1&&!lead) return num*ten[pos+1]+dp[pos];
    ll up=limit?a[pos]:9;
    ll tmp=0;
    if(who!=0)
        for(int i=0;i<=up;i++)
        tmp+=dfs(pos-1,num+(who==i),0,limit&&a[pos]==i,who);
    else
        for(int i=0;i<=up;i++)
        tmp+=dfs(pos-1,num+(who==i&&!lead),lead&&i==0,limit&&a[pos]==i,who);
    if(!limit&&!lead) dp[pos]=tmp;
    return tmp;
}
ll solve(ll n,ll m)
{
    ll pos=0;
    while(n)
    {
        a[pos++]=n%10;
        n/=10;
    }
    return dfs(pos-1,0,1,1,m);
}
int main()
{
    ll x,y;
    ios::sync_with_stdio(false);
    init();
    cin>>x>>y;
    for(ll i=0;i<=9;i++)
    {
        memset(dp,-1,sizeof(dp));
        cout<<solve(y,i)-solve(x-1,i)<<endl;
    }
    return 0;
}

  

  

时间: 2024-10-09 05:50:31

51nod 1042 数字0-9的数量 (数位dp、dfs、前导0)的相关文章

Poj-3286- How many 0&#39;s? - 【基础数位DP】

How many 0's? Description A Benedict monk No.16 writes down the decimal representations of all natural numbers between and including m and n, m ≤ n. How many 0's will he write down? Input Input consists of a sequence of lines. Each line contains two

[Codeforces 258B &amp; 259 D]Little Elephant and Elections 数位dp+dfs

http://codeforces.com/problemset/problem/258/B 题目大意: 说七个party选择数字(各不相同) 而规定的小象的party选择的数字之中所拥有的数字4和7的个数要比其他六个party拥有的个数之和还要严格多,询问方案数. 如m=7时其余的随意选择至少会拥有一个4或7,与题意矛盾,故方案数为0 m=8时,7 1 2 3 5 6 8是一种合法方案 思路: 由于小象的party选到的数字所含4和7的个数至多和m的位数一样多,则枚举小象的party所含4和7

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<

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

给出一段区间a-b,统计这个区间内0-9出现的次数. 比如 10-19,1出现11次(10,11,12,13,14,15,16,17,18,19,其中11包括2个1),其余数字各出现1次. 输入 两个数a,b(1 <= a <= b <= 10^18) 输出 输出共10行,分别是0-9出现的次数 输入样例 10 19 输出样例 1 11 1 1 1 1 1 1 1 1 解:被这道题卡了好久...最后自己找了个数模拟了一边流程.举个例子简单说说:对于数5314,我们可以将它拆分为[5310

CodeVS 1359 数字计数 51nod 1042 数字0-9的数量 Pascal

题目大意: 我的代码又臭又长,但是毕竟是我这个jr想了几天才推出的公式,看别的大神都写数位DP,所以我决定分享一下我的思路.我认为我的思路一向是最好理解的! 要分两种情况讨论: 1.0的情况.我们首先推出0~9中只有1个0,在0~99中有(1+(9*100*1))个0{第一位可以为1~9,第二位可以为0~9,0只可以放在后者,所以乘1},在0~999中有((1+(9*100*1))+(9*101*2))个0~6666为例,先算出0~999中0的个数,在算出1000~5999中0的个数,则为(10

51nod 1009 - 数字1的数量 - [数位DP][模板的应用以及解释]

题目链接:https://www.51nod.com/onlineJudge/questionCode.html#!problemId=1009 基准时间限制:1 秒 空间限制:131072 KB 给定一个十进制正整数N,写下从1开始,到N的所有正数,计算出其中出现所有1的个数. 例如:n = 12,包含了5个1.1,10,12共包含3个1,11包含2个1,总共5个1. Input 输入N(1 <= N <= 10^9) Output 输出包含1的个数 Input示例 12 Output示例

BZOJ1833 [ZJOI2010]count 数字计数 【数学 Or 数位dp】

题目 给定两个正整数a和b,求在[a,b]中的所有整数中,每个数码(digit)各出现了多少次. 输入格式 输入文件中仅包含一行两个整数a.b,含义如上所述. 输出格式 输出文件中包含一行10个整数,分别表示0-9在[a,b]中出现了多少次. 输入样例 1 99 输出样例 9 20 20 20 20 20 20 20 20 20 提示 30%的数据中,a<=b<=10^6: 100%的数据中,a<=b<=10^12. 题解 你以为我真的会写数位dp? 首先容斥一下,转化为求小于等于

hdu3652 B-number(数位dp+dfs)

B-number Time Limit: 2000/1000 MS (Java/Others) Memory Limit: 32768/32768 K (Java/Others) Total Submission(s): 3376 Accepted Submission(s): 1891 Problem Description A wqb-number, or B-number for short, is a non-negative integer whose decimal form con

51nod 1009 数字1的数量 数位dp

1009 数字1的数量 基准时间限制:1 秒 空间限制:131072 KB 给定一个十进制正整数N,写下从1开始,到N的所有正数,计算出其中出现所有1的个数. 例如:n = 12,包含了5个1.1,10,12共包含3个1,11包含2个1,总共5个1. Input 输入N(1 <= N <= 10^9) Output 输出包含1的个数 Input示例 12 Output示例 5 #include<bits/stdc++.h> using namespace std; #define