您的位置:首页 > 其它

UVA 11038 - How Many O's?(计数问题)

2014-05-10 19:36 411 查看


题目链接: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;
}
内容来自用户分享和网络整理,不保证内容的准确性,如有侵权内容,可联系管理员处理 点击这里给我发消息
标签: