UVA11038 How Many O's?题解

本文提供了一种使用C++解决UVa 11038问题“有多少个0”的方法。该算法能计算从0到给定数b之间的所有整数中0的个数,并且时间复杂度与b的位数呈线性关系。

原文链接:http://www.algorithmist.com/index.php/User:Sweepline/UVa_11038.cpp


AC的C++语言程序如下:

// C++ solution for problem 11038 - "How Many 0's"
#include <cstdio>
#include <cstring>
#include <algorithm>
using namespace std;
 
// Returns the number of zeroes in decimal representation of 0, 1, ..., b.
// Complexity: linear in the number of decimal digits of b.
long long solve(long long b) {
	if (b < 0) return 0;
 
	// Compute decimal representation of b
	char s[20];
	sprintf(s, "%lld", b);
	int n = strlen(s);
 
	// Compute powers of 10
	long long ten[20] = { 1 };
	for (int n = 1; n < 20; n++)
		ten[n] = ten[n-1] * 10;
 
	// Compute suffixes of b.suf[k] = atoll(s+k).
	long long suf[20];
	suf[n] = 0;
	for (int i = n-1; i >= 0; i--)
		suf[i] = suf[i+1] + (s[i] - '0') * ten[n-i-1];
 
	long long res = 1, pref = 0;
	for (int k = 1; k < n; k++) {
		pref = pref * 10 + (s[k-1] - '0');
		// pref is equal to integer, formed by first k digits of b.
 
		if (s[k] != '0')
			res += pref * ten[n-k-1];
		else
			res += (pref - 1) * ten[n-k-1] + suf[k+1] + 1;
	}
	return res;
}
 
int main() {
	long long m, n;
	while (scanf("%lld %lld", &m, &n) == 2 && m >= 0 && n >= 0) 
		printf("%lld\n", solve(max(m,n)) - solve(min(m,n)-1));
}



评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值