和蓝桥杯的《计数问题》很像
#include<algorithm>
#include<vector>
using namespace std;
int main(){
long long n,ans=0,cnt=1,i=0,high;
vector<long long>v(12);//记录0~10**v[i]-1共有多少1
v[0]=0;
for(int i=1;i<12;i++){
v[i]=10*v[i-1]+cnt;
cnt*=10;
}
scanf("%lld",&n);
cnt=1;
while (n>=cnt*10){//从高位开始计算
i+=1;
cnt*=10;
}
while (i>=0){
high=n/cnt;
if (high>1){//第一位>1
ans+=high*v[i]+cnt;
}
else if(high==1){//第一位==1
ans+=v[i]+n%cnt+1;
}
n%=cnt;
cnt/=10;
i-=1;
}
printf("%lld",ans);
return 0;
}