首页 > 代码库 > UVA 11038 - How Many O's?(计数问题)
UVA 11038 - How Many O's?(计数问题)
题目链接:11038 - How Many O‘s?
题意:求[a.b]之间,0出现的次数。
思路:一开始一直往数位DP上去想,结果发现挺复杂的。。
把问题先转化为求0 - num的个数,在用到b的个数减去到a的个数
其实只要利用计数的乘法和加法原理,把数字对应的每一位的分成左右两边,利用乘法原理求总数,在用加法原理把所有的总数加起来就是总情况数。那么讨论一下分成两边的情况。举个例子
比如23045
设中间位为mid,如果mid不为0,假如求到4这个位,那么左边的情况就有[1-230]种情况,而右边则有[0 - 9]种情况,再如果求到3这个位,左边就有[1- 2]种,右边有[0 - 999]种,因为右边不管怎么取都不会超过数字。
如果mid为0,那么左边取[1-22]时,右边可以随便取为[1-100],如果左边取23,右边只能取[0-45]。这样总情况由低位一直往高位去计算就能算出来了
代码:
#include <stdio.h> #include <string.h> long long a, b; long long solve(long long left) { if (left < 0) return 0; long long ans = 1, mid, right = 0, j = 1; while (left >= 10) { mid = left % 10; left /= 10; if (mid) ans += left * j; else ans += (left - 1) * j + right + 1; right = right + mid * j; j *= 10; } return ans; } int main() { while (~scanf("%lld%lld", &a, &b) && a != -1 || b != -1) { printf("%lld\n", solve(b) - solve(a - 1)); } return 0; }
声明:以上内容来自用户投稿及互联网公开渠道收集整理发布,本网站不拥有所有权,未作人工编辑处理,也不承担相关法律责任,若内容有误或涉及侵权可进行投诉: 投诉/举报 工作人员会在5个工作日内联系你,一经查实,本站将立刻删除涉嫌侵权内容。