题目链接:https://www.luogu.com.cn/problem/P2602

题目大意:

计算区间 \([L,R]\) 范围内 \(0 \sim 9\) 各出现了多少次?

解题思路:

使用 数位DP 进行求解。

定义一个结构体数组 \(f[pos][all0]\) 表示满足如下条件时 \(0 \sim 9\) 出现的次数:

  • 当前所在数位为第 \(pos\) 位;
  • \(all0\) 为 \(1\) 表示当前状态之前一直都是前置 \(0\) ,为 \(0\) 表示前面的数位上面出现过不为 \(0\) 的数。

然后定义一个返回值为此结构体类型的函数 dfs(int pos, int all0, bool limit) 进行求解,其中:

  • \(pos\) 和 \(all0\) 的含义同上;
  • \(limit\) 表示是否处于限制状态。

实现代码如下:

// P2602 [ZJOI2010]数字计数
#include <bits/stdc++.h>
using namespace std;
long long cnt[10], pow10[22], num;
int a[22];
struct Node {
long long arr[10];
Node() { memset(arr, 0, sizeof(arr)); }
void merge(Node v) {
for (int i = 0; i < 10; i ++)
arr[i] += v.arr[i];
}
} f[22][2];
bool vis[22][2];
void init() {
pow10[0] = 1;
for (int i = 1; i <= 18; i ++) pow10[i] = pow10[i-1] * 10;
}
Node dfs(int pos, int all0, bool limit) {
if (pos < 0) return Node();
if (!limit && vis[pos][all0]) return f[pos][all0];
int up = limit ? a[pos] : 9;
Node tmp = Node();
for (int i = 0; i <= up; i ++) {
if (i == 0 && all0 && pos>0) ;
else {
if (limit && i==up) tmp.arr[i] += num % pow10[pos] + 1;
else tmp.arr[i] += pow10[pos];
}
tmp.merge(dfs(pos-1, all0&&i==0, limit&&i==up));
}
if (!limit) {
vis[pos][all0] = true;
f[pos][all0] = tmp;
}
return tmp;
}
Node get_num(bool minus1) {
long long x;
cin >> x;
if (minus1) x --;
num = x;
int pos = 0;
while (x) {
a[pos++] = x % 10;
x /= 10;
}
if (num == 0) a[pos++] = 0;
return dfs(pos-1, true, true);
}
int main() {
init();
Node res_l = get_num(true);
Node res_r = get_num(false);
for (int i = 0; i < 10; i ++) {
if (i) putchar(' ');
cout << res_r.arr[i] - res_l.arr[i];
}
cout << endl;
return 0;
}

最新文章

  1. 调试python程序
  2. iOS 设置导航栏的颜色和导航栏上文字的颜色
  3. ylbtech-LanguageSamples-Unsafe(不安全代码)
  4. Linux 64位编译\链接32位程序
  5. oracle顺序控制语句goto、null和分页过程中输入输出存储、java程序的调用过程
  6. 单元测试中Assert类
  7. Codevs_1017_乘积最大_(划分型动态规划/记忆化搜索)
  8. 项目总结——SqlParameter的参数设置长度(size属性)
  9. [转]SecureCRT右键粘贴的设置
  10. Cocos2D:塔防游戏制作之旅(十八)
  11. mongdb的索引及备份
  12. mybatis根据数据库表结构自动生成实体类,dao,mapper
  13. 将数组Arrays转成集合List
  14. Solr版本问题分析
  15. Positioning
  16. 服务器启动报mybatis配置错误
  17. linux sed在某些字符串的下一行插入内容?sed在下一行插入?
  18. 消息 14607,级别 16,状态 1,过程 sp_send_dbmail,第 141 行 profile 名称无效
  19. hashset和treeset的区别
  20. Wannafly挑战赛7 D - codeJan与青蛙

热门文章

  1. 伪静态的实现方法:IIS环境下配置
  2. Freeware Tools For Linux, http://www.debianhelp.co.uk/tools.htm
  3. MaxCompute 预付费标准版VS套餐版
  4. 使用FormData格式上传图像并预览图片
  5. oracle强制索引失效
  6. [C#] Parallel.For的线程数
  7. while循环计算1-100和,1-100内偶数/奇数/被整除的数的和
  8. POI 导入、导出Excel
  9. Codeforces Round #184 (Div. 2)
  10. win10系统激活 快捷方式