数数字(UVa1225)打表法

13 篇文章 1 订阅
2 篇文章 0 订阅
博客介绍了如何利用打表法解决UVa1225数数字的问题,即统计1到N的连续整数中每个数字出现的次数。通过AC代码和分析,解释了如何构建ans数组并进行动态更新,最终输出0到9每个数字的出现次数。
摘要由CSDN通过智能技术生成

原题:

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.

  • 1
    点赞
  • 0
    收藏
    觉得还不错? 一键收藏
  • 0
    评论
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值