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;
}