【递归与递推】计数器
【递归与递推】计数器
题目描述
一本书的页数为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\n",a[i]); //system("pause"); return 0; }