计算1到n中的1的个数

来源:互联网 发布:群发短信软件电脑版 编辑:程序博客网 时间:2024/06/05 23:03

b[i]表示n数字从小到大第i位是什么

c[i]表示1到b[i]b[i-1]....1中的1的个数,a[i]表示1到10^i-1中有几个1

sum表示从低位向高位循环过程中累计的值,最后是n


接下来递推

if(b[i]==0) c[i]=c[i-1] 是0的话和前一位的值是一样的

else if   (b[i]==1) c[i]=a[i-1]+sum+1+c[i-1]   是1的话     考虑    比如12345         就是0------9999 (a[i-1])    +   10000---12345 中最高位的1(sum+1)   +   10000--- 123456中 0000--2345 中的1(c[i-1])    

else   c[i]=a[i-1]*b[i]+pow(10,i-1)+c[i-1]     大于1的话 考虑     比如22345      就是   0开头(0000--9999)+ 1开头(0000---9999)     先不看最高位  就是 a[i-1]*b[i]

然后  2开头(0000---2345) 就是  c[i-1]     最后看       最高位为1的情况,  只算这个最高位的 pow(10,i-1)

#include<iostream>#include<stdio.h>#include<string.h>#include<algorithm>#include<map>#include<queue>#include<math.h>#include<stack>using namespace std;#define LL long long#define mp(a,b) make_pair((a),(b))#define clr(x,a) memset(x,a,sizeof(x))#define INF 0x3f3f3f3f#define lb(x) ((x)&(-x))#define rep(i,a,b) for(int i=a;i<=b;i++)const int N=1005,siz=1e9;const int MOD=1e9+7;int d,n;int a[10];int b[10];int c[10];int main(){    //freopen("aaa.txt","r",stdin);    //freopen("bbb.txt","w",stdout);    a[1]=1;a[0]=0;    for(int i=2;i<=8;i++){        a[i]=10*a[i-1]+pow(10,i-1);    }    while(~scanf("%d",&n)){        int num=0;        int m=n;        while(n){            b[++num]=n%10;            n/=10;        }        int sum=m%10;        c[1]=(sum==0?0:1);        for(int i=2;i<=num;i++){         if(b[i]==0) c[i]=c[i-1];         else  if(b[i]==1) c[i]=c[i-1]+1+sum+a[i-1];         else c[i]=c[i-1]+b[i]*a[i-1]+pow(10,i-1);         sum=sum+b[i]*pow(10,i-1);                    }        printf("%d\n",c[num]);    }    return 0;}


0 0
原创粉丝点击