题解 P1554 【梦中的统计】
stone_juice石汁 · · 题解
挑战最短题解(第三弹)
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;的好习惯哦!
(悄悄地不要脸地求个赞)