UVa 1640 The Counting Problem (数位DP)

题目

题目大意

给出\(a\)、\(b\), 统计\(a\)和\(b\)(包含\(a\)和\(b\))之间的整数中, 数字\(0, 1, 2, 3, 4, 5, 6, 7, 8, 9\)分别出现了多少次。\(1 ≤ a, b ≤ 10^8\)。注意, \(a\)有可能大于\(b\)。

题解

设\(f_d(n)\)表示\(0 \cdots n\)中数字\(d\)出现的个数, 则求的是\(f_d(a) - f_d(b - 1)\)。

暴力显然是会\(TLE\)的, 我们可以分段来求。例如我们要求\(0 \cdots 234\)中每个数字的个数, 可以分成一下几个区间:

  1. \([0, 9]\)
  2. \([10, 99]\)
  3. \([100, 199]\)
  4. \([200, 229]\)
  5. \([230, 234]\)

递归求解就可以了。

代码

#include <cstdio>
#include <cstring>
int a[10], b[10];
inline void DepthFirstSearch(const int &n, const int &m, register int *arr) {
    register int x(n / 10), y(n % 10), temp(x);
    for (register int i = 1; i <= y; i++) {
        arr[i] += m;
  }
    for (int i = 0; i < 10; i++) {
        arr[i] += m * x;
  }
    while (temp) {
        arr[temp % 10] += m * (y + 1);
        temp /= 10;
    }
    if (x) {
        DepthFirstSearch(x - 1, m * 10, arr);
  }
}
int main(int argc, char const *argv[]) {
    register int x, y;
    while (~scanf("%d %d", &x, &y) && (x || y)) {
        if (x > y) x ^= y ^= x ^= y;
    memset(a, 0, sizeof(a)),
        memset(b, 0, sizeof(b));
        DepthFirstSearch(x - 1, 1, a),
        DepthFirstSearch(y, 1, b);
        for (register int i(0); i < 10; ++i) {
      printf(i == 9 ? "%d\n" : "%d ", b[i] - a[i]);
    }
    }
    return 0;
}

原文地址:https://www.cnblogs.com/forth/p/9722945.html

时间: 2024-08-01 15:06:35

UVa 1640 The Counting Problem (数位DP)的相关文章

UVA 1640 The Counting Problem UVA1640 求[a,b]或者[b,a]区间内0~9在里面各个数的数位上出现的总次数。

/** 题目:UVA 1640 The Counting Problem UVA1640 链接:https://vjudge.net/problem/UVA-1640 题意:求[a,b]或者[b,a]区间内0~9在里面各个数的数位上出现的总次数. 思路:数位dp: dp[leadzero][i][j][k]表示前面是否选过非0数,即i长度之后可以第一个出现0,而不是前导0,长度为i,前面出现j,k次,j出现的次数. */ #include<iostream> #include<cstri

UVA 1640 The Counting Problem

https://vjudge.net/problem/UVA-1640 题意:统计区间[l,r]中0——9的出现次数 数位DP 注意删除前导0 #include<cmath> #include<cstdio> #include<cstring> #include<algorithm> using namespace std; int ans[10],a[10],dp[10][10],bit[10]; int dfs(int dep,int ty,bool l

poj2282 The Counting Problem 数位dp

题意:给两个数l,r,求[l,r]区间内这么多数包含多少个"0" "1" "2"..."9". 比如[1 10] 除了"1"有2个,其余数字均只有1个. 思路:数的范围为1e8,又是数的统计,一看就是数位dp.设dp[ i ] [ pos ] [ cnt ]为当前考虑数字为i,且当前考虑pos位,之前的位已经 有cnt个数字i,之后(pos+1)位与之前数位组合含数字i的个数.那么除了数字"0&q

UVa 1640 - The Counting Problem(数论)

链接: https://uva.onlinejudge.org/index.php?option=com_onlinejudge&Itemid=8&page=show_problem&problem=4515 题意: 给出整数a.b,统计a和b(包含a和b)之间的整数中,数字0,1,2,3,4,5,6,7,8,9分别出现了多少次.1≤a,b≤1e8. 分析: 解决这类题目的第一步一般都是:令f(n,d)表示0-n中数字d出现的次数,则所求的就是f(b,d)-f(a-1,d).例如,

uva 11361 Investigating Div-Sum Property 数位dp

// uva 11361 Investigating Div-Sum Property 数位dp // // 题目大意: // // 给你一个整数a和一个整数b,问在[a,b]范围内,有多少个自身被k整除并且 // 各位数之和也能被k整除.比如k = 7 ,322满足条件,因为332能被整除7,并 // 3 + 2 + 2 = 7 也能被7整除 // // 解题思路: // // 求一个区间的题目,这类题目,往往可以转化为不超过x的f(x).则最后要求 // 的就是f(b) - f(a-1).如

uva 10712 - Count the Numbers(数位dp)

题目链接:uva 10712 - Count the Numbers 题目大意:给出n,a,b:问说在a到b之间有多少个n. 解题思路:数位dp,dp[i][j][x][y]表示第i位为j的时候,x是否前面是相等的,y是否已经出现过n.对于n=0的情况要特殊处理前导0,写的非常乱,搓死. #include <cstdio> #include <cstring> #include <iostream> #include <algorithm> using na

uva 10401 Injured Queen Problem(DP)

uva 10401 Injured Queen Problem 题目大意:这是一个变形的N皇后问题,皇后不再是占据一行一列以及斜线,她占据的只是她周围的一圈以及她所在的一列.题目给出一个含有问号,数字和字母的字符串.第i个字符是问号代表皇后在第i列的任意一行,若第i个字符是数字或字母X(1-F)代表皇后在第i列的X行.求满足该字符串的摆放方式的方法一共有几种. 解题思路:从第一列开始往后递推.dp[i][j]表示的是结合j - 1列的摆放方式,将皇后放在(i, j)的位置会有几种情况. #inc

UVA 12486 Space Elevator(数位DP)

题目pdf:http://acm.bnu.edu.cn/v3/external/124/12486.pdf 大致题意:求第n个不包含"4"和"13"为子串的数是多少 , n<= 1e18 思路:就是一般的数位DP,二分答案,对答案的数求数位DP算出此数以内有多少个满足条件的数 但是....居然答案爆long long,要用unsigned long long 才能过,就这个坑点 // 0 ms 0 KB 2633 B 2015-08-15 01:02:36 /

UVA 1225 Digit Counting(统计数位出现的次数)

Digit Counting Time Limit: 3000MS   Memory Limit: Unknown   64bit IO Format: %lld & %llu SubmitStatus Description Trung is bored with his mathematics homeworks. He takes a piece of chalk and starts writing a sequence of consecutive integers starting