问题转化为求0到x的所有数中0的数量,相当于前缀和。
求前缀和的方法:依次求每一位上是0的情况数,这是要分这一位上原数是不是零这两种情况讨论的。
求的过程中需要知道当前处理这一位的左边,右边数各是多少。一个方便的方法是只用3个数left,right,cur维护,从右往左递推修改这3个数。
代码:
#include <iostream>
#include <cstdio>
#include <cstring>
using namespace std;
#define LL long long
LL solve(LL n){
if(n<0) return 0;
LL cur=n%10;
LL right=0;
LL left=n/10;
LL res=0;
LL k=1;
while(left>0){
if(cur!=0){
res+=k*left;
}
else {
res+=k*(left-1);
res+=(right+1);
}
right+=cur*k;
k*=10;
cur=left%10;
left/=10;
}
return res+1;
}
int main(){
LL m,n;
while(~scanf("%lld%lld",&m,&n)){
if(m<0) break;
printf("%lld\n",solve(n)-solve(m-1));
}
return 0;
}