UVA1640TheCountingProblem

来源:互联网 发布:单片机原理及 编辑:程序博客网 时间:2024/06/11 20:49
//UVA1640TheCountingProblem#include<cstdio>#include<cstring>#include<algorithm>using namespace std;const int maxn = 8;int cnt[maxn + 1], pow10[maxn + 1];int f(int d, int n) {char s[10];sprintf(s, "%d", n);int len = strlen(s);int ans = 0;for(int i = 1; i < len; i++) {if(i == 1) ans++;else {    ans += 9 * cnt[i - 1];        if(d > 0) ans += pow10[i - 1];    }}int pre[10];for(int i = 0; i < len; i++) {pre[i] = (s[i] - '0' == d) ? 1 : 0;if(i) pre[i] += pre[i - 1]; }for(int i = 0; i < len; i++) {int end = s[i] - '0' - 1;//防止超过n,且便于计算 int start = 0;if(i == 0 && len > 1) start = 1;//防止前导零for(int digit = start; digit <= end; digit++) {ans += cnt[len - 1 - i];//累加在本位不变的情况下,后面位中所需d的个数 if(d == digit) ans += pow10[len - 1 - i];//当本位为d时,累加本位出现的次数 if(i > 0) ans += pre[i - 1] * pow10[len - 1 - i];//累加之前位出现的次数(由于每次遍历的时候都要-1) } }return ans; }int main() {int a, b;pow10[0] = 1;for(int i = 1; i <= maxn; i++) pow10[i] = pow10[i - 1] * 10;for(int i = 1; i <= maxn; i++)  cnt[i] = i * pow10[i - 1];while(scanf("%d%d", &a, &b) == 2 && a) {if(a > b) swap(a, b);printf("%d", f(0, b + 1) - f(0, a));for(int d = 1; d <= 9; d++) printf(" %d", f(d, b + 1) - f(d, a));printf("\n");}return 0;}/*1 1044 497346 5421199 17481496 14031004 5031714 1901317 8541976 4941001 19600 0*/