原题:
Trung is bored with his mathematics homeworks. He takes a piece of chalk and starts writing a sequence of consecutive integers starting with 1 to N (1 < N < 10000). After that, he counts the number of times each digit (0 to 9) appears in the sequence. For example, with N = 13, the sequence is:12345678910111213
In this sequence, 0 appears once, 1 appears 6 times, 2 appears 2 times, 3 appears 3 times, and each digit from 4 to 9 appears once. After playing for a while, Trung gets bored again. He now wants to write a program to do this for him. Your task is to help him with writing this program.
Input
The input file consists of several data sets. The first line of the input file contains the number of data sets which is a positive integer and is not bigger than 20. The following lines describe the data sets. For each test case, there is one single line containing the number N.
Output
For each test case, write sequentially in one line the number of digit 0,1,...9 separated by a space.
Sample Input
2
3
13
Sample Output
0 1 1 1 0 0 0 0 0 0
1 6 2 2 1 1 1 1 1 1
大概意思:
把前n(n≤10000)个整数顺次写在一起:123456789101112…数一数0~9各出现多少次(输出10个整数,分别是0,1,…,9出现的次数)。
用打表法练练这道题目。先放AC代码,再讲解。
AC代码:
#include<iostream>
using namespace std;
int ans[10000][10];
int main()
{
//1.保存输入,同时找到最大值
int N;
cin>>N;
int a[N];
int x;
int max=0;
for(int i=0; i<N; i++)
{
cin>>x;
if(x>max)max=x;
a[i]=x;
}
//2.打表
for(int i=1; i<=max; i++)
{
for(int k=i; k>0; k/=10)ans[i][k%10]++;
for(int k=0; k<=9; k++)ans[i][k]+=ans[i-1][k];
}
//3.输出
for(int i=0; i<N; i++)
{
for(int j=0; j<=9; j++)
{
if(j)cout<<" ";
cout<<ans[a[i]][j];
}
cout<<endl;
}
return 0;
}
分析:
首先,ans数组是要干什么用的,ans,答案,所以里面放的就是答案啦~哈哈哈
ans【i】【k】,代表的是当N=i,的时候,k(0-9)共出现了多少次。
如果不太明白可以看一下下面这张图片。
这张图片输出的是N<=10的情况。
我们看一下,当i=1,时候,只有1,所以只有ans[1][1]=1;
当i=9的时候,序列是123456789,所以从a[9][1]到a[9][9]全部都为1;
当i=10的时候,序列是12345678910,多了一个10,所以与i=9时相比,0多了一个,1多了一个。
通过上面的分析,我们就可以打表了。
首先是把输入给保存进来,然后同时找到最大值。为什么要找最大值呢?因为,假设你的最大值是100,那么i=100以后的数据打完表之后也用不到的。顺便说一句,找最大值本来应该是先把第一个元素赋值给max的,但因为这里N>1,所以直接令max=0就OK。
然后打表。
我们看一下刚刚上面 i =10的例子。i=10的情况我们可以看成i=9的情况,再加上10这个数字给它带来的改变。所以:
ans[i][k%10]++;
ans[i][k]+=ans[i-1][k];
最后输出。
因为我们第一步已经用一个数组保存了,所以我们取数组中的每一个元素,然后输出ans里面的答案就OK了。cout<<ans[a[i]][j];
然后 if(j)cout<<" ";这是为了控制,每一行最后一个元素后面不要有空格。
Over.