题解 P1554 【梦中的统计】

· · 题解

挑战最短题解(第三弹)

hia hia hia,我又来giao事情了

这道红题其实很水(废话...)一遍过小意思啦。乍一看题解,突然发现我的解法好像是最短的(~逃)。然后就想过来水一发题解了。

思路:

首先,N和M都没过int的范围,所以不用想着去开long long(但是有些坑题就要开,一定要注意数据范围)。

然后发现N-M ≤500,000。没错,暴力枚举能水过去。果断暴力(手动滑稽)。

那么怎么处理这道题呢?

首先,开for循环是必须的。我们需要枚举两个数N,M之间的所有数然后来处理问题。

cin>>n>>m;
for(int i=n;i<=m;i++)
{
    代码
}
//如上

那怎么处理每个数,计算出它们0-9出现的次数呢?

这里介绍两个非常好用的运算符:/ 和 %

(懂得这两个符号怎么用的DALAO不用看了)

1、

/ 就是除号嘛。但是它和我们平时的除法不太一样。它在处理int的时候,由于只能存整数,所以除完后存的数会丢掉小数。(注意:不是四舍五入)

例如:123/4=30(int型)

那么我们可以利用这个特性。我们如果把一个int型的数/10,它就丢掉了它的最后一位

例如:236/10=23(最后一位没了)

2、

% 求余数,也称作模。就是求一个数除另外一个数的余数。

例如:123/4=30···3。那么123%4=3。

这个东西也是一个很好用的东西。和上面类似,我们可以把1个数%10,求他的最后一位。

例如:236%10=6 (最后一位)

综合

有了上面这两个方法,我么就可以这样做:取一个数的最后一位(%10),再把它的最后一位扔掉,记录。然后再取新的最后一位,再把它扔掉,记录。循环直到这个数变成0(无法再取)

画个表就是这样的:

numa

1234-----取4,记录,扔掉4。

123-------取3,记录,扔掉3。

12---------取2,记录,扔掉2。

1-----------取1,记录,扔掉1。

0(结束)

这是处理一个数的过程,把实现这个过程的程序放进枚举循环里就行了。

最后一个小东西:存储。

现在我知道怎么处理这些数,怎么存这些数出现多少次呢?

很简单,创建一个数组js[10],这个数出现一次,就把相应的数组下表个数++。

例如:取到3,js[3]++;

最后,存储完之后,用个循环挨个输出每个数的出现次数就over啦!

上代码!

#include <bits/stdc++.h>//华丽地开头 
using namespace std;
int js[10],n,m;
int main()
{
    cin>>n>>m;//n,m如题 
    for(int i=n;i<=m;i++)for(int tmp=i;tmp;tmp/=10)js[tmp%10]++; 
    for(int i=0;i<=9;i++)cout<<js[i]<<" ";
}
/*for(int tmp=i;tmp;tmp/=10)js[tmp%10]++;
  解释:定义一个tmp代替要处理的数(tmp=i)
  当tmp=0时结束循环。(中间可以直接写  tmp)
  每次循环后把tmp最后一位扔掉。
  每次循环把tmp最后一个数记录进数组。
*/ 

注意!各位童鞋一定要加return 0;我是因为赶最短代码没写!要养成写return 0;的好习惯哦!

(悄悄地不要脸地求个赞)