POJ 3286:统计a--b之间,0出现的次数
#include <iostream> #include <cstdio> using namespace std; typedef long long ll; ll a, b; ll ansa[10], ansb[10]; void count_digits(ll s, ll ans[], ll times = 1) {//求1-s之间的所有数中 0的个数,1的个数,2.....其中ans[0...9]为返回值 ll i, d, p; if (s <= 0) return; d = s % 10; p = s / 10; for (i = 1; i <= d; i++) ans[i] += times; while (p > 0) { ans[p % 10] += (d + 1) * times; p = p / 10; } for (i = 0; i <= 9; i++) ans[i] += times * (s / 10); times *= 10; count_digits((s / 10) - 1, ans, times); return; } //以上是区间统计数字的模板.... int main(){ while(scanf("%lld%lld",&a,&b)!=EOF,a>=0&&b>=0){ if(a == 0 && b == 0){//如果区间的两个端点都是0,则0出现的次数是1... printf("1\n"); continue; } if(a > b){ swap(a,b); } bool flag = false; if(a == 0){ flag = true; } a -= 1; memset(ansa,0,sizeof(ansa)); memset(ansb,0,sizeof(ansb)); count_digits(a,ansa); count_digits(b,ansb); if(flag){//如果区间的左端点是1,则0出现的次数+1 ansb[0]++; } printf("%lld\n",ansb[0] - ansa[0]); } return 0; }
#include <iostream> #include <cstdio> using namespace std; typedef long long ll; ll a, b; ll ansa[10], ansb[10]; void count_digits(ll s, ll ans[], ll times = 1) {//求1-s之间的所有数中 0的个数,1的个数,2.....其中ans[0...9]为返回值 ll i, d, p; if (s <= 0) return; d = s % 10; p = s / 10; for (i = 1; i <= d; i++) ans[i] += times; while (p > 0) { ans[p % 10] += (d + 1) * times; p = p / 10; } for (i = 0; i <= 9; i++) ans[i] += times * (s / 10); times *= 10; count_digits((s / 10) - 1, ans, times); return; } int main(){ while(scanf("%lld%lld",&a,&b)!=EOF,a||b){ memset(ansa,0,sizeof(ansa)); memset(ansb,0,sizeof(ansb)); if(a > b){ swap(a,b); } a -= 1; count_digits(a,ansa); count_digits(b,ansb); int i; for(i = 0 ; i < 10 ; ++i){ printf("%lld ",ansb[i] - ansa[i]); } printf("\n"); } return 0; }