统计数字
Time Limit: 3 second
Memory Limit: 2 MB
【问题描述】
一本书的页数为N,页码从1开始编起,请你求出全部页码中,用了多少个0、1、2、3、4、5、6、7、8、9。其中每个页码不含多余的0,如N=123时,第5页不是005,只是5,第12页不是012,只是12。【输入】
输入文件仅一行,一个正整数N(N≤109),表示总的页码数。
【输出】
输出文件十行,第K行为数字k-1的个数,即第一行为数字0的个数,第二行为数字1的个数,第三行为数字2的个数,以此类推。
【输入样例】
11【输出样例】
1 4 1 1 1 1 1 1 1 1
【题解】
这题很恶心,没错 又是恶心这个词,以后只可能会越来越多地出现这个词。不会减少。。。
我是看着题解写的程序。
首先,从000-999 我们不要删掉多余的0,那么我们会有1000个3位数,然后一共有3000个数字出现过,可以想想0-9,每个数字都只出现一次,00-99,也可以知道0-9每个数字都出现相同的次数。推广一下,000-999每个数字出现的次数也是一样的。
然后3000个数字,0-9有10个,则每个数字都有用到300次。
先别问我0的事!
然后我们举个例子。
6147
我们先看6,6之前有0-5,后3位,都从000-999变化,刚才我们算出来了,每个数字都会用到300次,0-5有6位,所以a[0..9]+=6*300;
然后是0-5这6个数字作为第一位,每个都出现过1000次,即0XXX 1XXX 2XXX...其中XXX ∈ [000,999];
最后是6,6我们要单独处理,要加上148,即6XXX,XXX∈[000..148];
然后处理1,4,7就好。
(这里你用while已经能写出来了,只要按照6的规律就可以)
接下来是0的问题了。
①
先从只有一位数的情况开始。
比如6;
我们先会看看6后面有没有数字,没有。
然后看看6前面有没有数字,有。要加上几呢? 假设l是数字的长度,我们肯定会这样做的
t = 1
for (int i = 1; i<=l-1;i++)
t = t *10;
这里如果是上面说的6174,l=4,则t=1000;
但是这里我们是以6为例,所以t = 1;
然后for (int i = 0;i <=5;i++)
a[i]+=t;
这里已经多出来一个0了。
剩下步骤省略。。
対,如果一位数字会多出1个0;
②
两位数。
比如12
我们先会看1后面有没有数字,有。
那就用下我们上面的公式。
0-9有10个一位数字。。。。然后每个数字被用一次。
则a[0..9]+=1;
//这里出现的0是多出的。
然后是0 被用了 10 次 0-9,
//这里的0也是多出来的。即00 01 02 03...09;
这里出现了11个多余的0
剩下步骤省略,因为没有出现多余的0.
③
111
④
1111
即多出的0是数字的位数。
【代码】
#include <cstdio> #include <iostream> #include <string> using namespace std; string s1; unsigned int n; int a[10]; void input_data() { cin >> s1; } void get_ans() { int l = s1.size(); //先获取数据的长度 for (int i = 0;i <= 9;i++) //每个数字使用的数目初始化 a[i] = 0; int t = 0; for (int i = 1;i <= l;i++) //先减去多余的0,即l(字母L)个1(数字1) t = t*10 + 1; a[0] -= t; //减去多余的0 while (l > 0) //如果还能继续减少长度 基本上写出第一层第二层就不会有问题了。 { int m = s1[0] - '0'; //先取出头数字 t = 1; for (int i = 1;i <= l-1;i++) //这里是6174中 6时的1000 t = t * 10; int tt = (t * (l-1))/10; //000 - 999 中每个数字被使用的次数 while进行一次就变成00-99 for (int i = 1;i <= m;i++) //0XXX 1XXX 2XXX 。。。。mXXX 中的 XXX for (int j = 0;j <= 9;j++) a[j] += tt; for (int i = 0;i <= m-1;i++) //0XXX 1XXX 2XXX ... mXXX中的 1..m a[i] += t; s1 = s1.erase(0,1); //这是从 int ttt =0; l = s1.size(); for (int i = 0;i <l;i++) ttt = ttt*10 + s1[i] - '0'; ttt++; a[m] += ttt; //这是统计6147 中的148. } } void output_ans() { for (int i = 0 ;i <= 9;i++) printf("%d ",a[i]); } int main() { input_data(); get_ans(); output_ans(); return 0; }