【递归与递推】计数器

 

【递归与递推】计数器

题目描述

一本书的页数为N,页码从1开始编起,请你求出全部页码中,用了多少个0,1,2,…,9。其中—个页码不含多余的0,如N=1234时第5页不是0005,只是5。

输入

一个正整数N(N≤109),表示总的页码。

输出

共十行:第k行为数字k-1的个数。

样例输入

11

样例输出

1
4
1
1
1
1
1
1
1
1

分析:写几个找规律,发现当前位对一个数的贡献与高位,低位,当前位均有关系;
分两种情况:
需要统计的数为0:
当前位为0,则贡献为(高位-1)*
10^低位位数+低位+1;
当前位不为0,则贡献为高位*10^低位位数;

被统计的数不为0:
当前位小于被统计数,则贡献为高位*
10^低位位数;
当前位等于被统计数,则贡献为高位*10^低位位数+低位+1;
当前位大于被统计数,则贡献为(高位+1)*10^低位位数;
代码:
#include <iostream>
#include <cstdio>
#include <cstdlib>
#include <cmath>
#include <algorithm>
#include <climits>
#include <cstring>
#include <string>
#include <set>
#include <map>
#include <queue>
#include <stack>
#include <vector>
#include <list>
#define rep(i,m,n) for(i=m;i<=n;i++)
#define rsp(it,s) for(set<int>::iterator it=s.begin();it!=s.end();it++)
#define mod 1000000007
#define inf 0x3f3f3f3f
#define vi vector<int>
#define pb push_back
#define mp make_pair
#define fi first
#define se second
#define ll long long
#define pi acos(-1.0)
const int maxn=1e6+10;
const int dis[][2]={0,1,-1,0,0,-1,1,0};
using namespace std;
ll gcd(ll p,ll q){return q==0?p:gcd(q,p%q);}
ll qpow(ll p,ll q){ll f=1;while(q){if(q&1)f=f*p%mod;p=p*p%mod;q>>=1;}return f;}
ll a[10],num,high,low,now,cnt;
int main()
{
    int i,j,m,n,k,t;
    scanf("%lld",&num);
    high=num/10,low=0,now=num%10,cnt=1;
    while(low!=num)
    {
        rep(i,0,9)
        {
            if(i==0)
            {
                if(now==0)a[i]+=(high-1)*cnt+1+low;
                else a[i]+=high*cnt;
            }
            else
            {
                if(now>i)a[i]+=(high+1)*cnt;
                else if(now==i)a[i]+=high*cnt+low+1;
                else a[i]+=high*cnt;
            }
        }
        now=high%10,high=high/10,cnt=cnt*10,low=num%cnt;
    }
    rep(i,0,9)printf("%lld
",a[i]);
    //system("pause");
    return 0;
}
 
 
原文地址:https://www.cnblogs.com/dyzll/p/5645401.html