本文主要是介绍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;
}
这篇关于UVA 11038 - How Many O's?(计数问题)的文章就介绍到这儿,希望我们推荐的文章对编程师们有所帮助!