题目意思很简单,要求输入一个整数N,判断从1到N中间出现所有数字中所携带1的个数,考虑1位数字0~9包含1个1,再考虑00~99包含20个1,再考虑000~999包含300个1,依次类推找出k+1位数字和k位数字所包含1的数量之间关系。接下来再从高位到低位不断分割,比如输入是1356,先找到000~999包含1个数,再找1000到1356包含1的个数,它包含1个数是357再加上356包含个数,依次不断向地位靠近。代码如下:
#include <iostream>
#include <cmath>
using namespace std;
long long sta[100][2];//由低到高每一位存储,比如sta[3][0]对应000~999有多少个1
//sta[3][1]存储千位上的数字
int main(){
long long N,temp,result=0;
cin>>N;
temp=N;
sta[1][0]=1;
sta[1][1]=temp%10;//个位上数字是多少
long long weiShu=2;
while(temp/10!=0){
sta[weiShu][0]=sta[weiShu-1][0]*10+pow(10,weiShu-1);//相邻位数之间满足递推关系
temp=temp/10;
sta[weiShu][1]=temp%10;
weiShu++;
}
weiShu--;//这个时候已经跳出while循环,weiShu多加了一次
long long left=N;
long long i=weiShu;
while(i>1){
if(sta[i][1]==1)
result=result+sta[i-1][0]+left-pow(10,i-1)+1;//后面添加的是最高位的1出现了几次
else
result=result+sta[i-1][0]*sta[i][1]+pow(10,i-1);
left=left-sta[i][1]*pow(10,i-1);
i--;
while(sta[i][1]==0){
i--;//为了防止中间输入1000023这样数字,中间出现很多0,需要依次去掉
if(i==1)
break;//去到个位数上就不用再去了
}
}
if(sta[1][1]>0)
result++;
cout<<result;
return 0;
}