【蓝桥第一周】计数的梦

来源:互联网 发布:电脑一维码识别软件 编辑:程序博客网 时间:2024/06/04 19:54

RQNOJ PID11 / 计数的梦

题目描述
      Bessie 处于半梦半醒的状态。过了一会儿,她意识到她好像在数羊,不能入睡。Bessie的大脑反应灵敏,仿佛真实地看到了她数过的一个又一个数。她开始注意每一个数码:每一个数码在计数的过程中出现过多少次?
      给出两个整数 M 和 N (1 <= M <= N <= 2,000,000,000 以及 N-M <= 500,000),求每一个数码出现了多少次。
      例如考虑序列 129..137: 129, 130, 131, 132, 133, 134, 135, 136, 137。统计后发现:
     1x0   1x5
     10x1 1x6
     2x2   1x7
     9x3   0x8
     1x4   1x9

输入格式
     共一行,两个用空格分开的整数 M 和 N
输出格式
      共一行,十个用空格分开的整数,分别表示数码(0..9)在序列中出现的次数
样例输入:
     129 137
样例输出:

     1 10 2 9 1 1 1 1 0 1 

解法一

[解题思路]

     因为M和N的取值范围为1 <= M <= N <= 2,000,000,000。所以用long long类型(long long的最大值:9,223,372,036,854,775,807)来存放,通过反复取模、做除法,统计各位数即可。

[代码实现]

#include<iostream>using namespace std;int ans[10];int main(){long long  M,N,temp;cin>>M>>N;for(long long i=M;i<=N;i++){temp=i;while(temp){ans[temp%10]++;temp/=10;}}for(int i=0;i<=9;i++)cout<<ans[i]<<" ";return 0;}
解法二
[解题思路]

        另一种实现方法就是把M,N通过字符串的形式输入,这种方法用于大数之间的运算,操作,这道题可以用高精度减法求出M,N之间的差(即有多少个数,N-M <= 500,000),再用高精度加法,M每次加1,进行统计。

[代码实现]

#include<iostream>#include<string>#include<cmath>using namespace std;int ans[10];int Hps(int Length,int *i_a,int *i_b){/* 该函数实现b-a,并返回sum */for(int i=0;i<Length;i++){ i_b[i]=i_b[i]-i_a[i];  }for (int i=0;i<Length-1;i++)           {                    if(i_b[i]<0)          {              i_b[i+1]-=1;              i_b[i]+=10;          }      }/* 无意义的0 */int book=0;  for (book=Length-1;book>=0;book--)      {          if(i_b[book])              break;      } /* 把数组转为整数 */int sum=0;for(int i=book;i>=0;i--){sum += pow(10,i)*i_b[i];}return sum;}int Hpa(int Length,int *i_a,int i){/* 该函数实现a+i(i<10),并返回book */i_a[0]+=i;/* 进位 */for(int i=0;i<Length;i++){if(i_a[i]>=10){i_a[i]-=10;i_a[i+1]+=1;}}int book=0;  for (book=Length-1;book>=0;book--)      {          if(i_a[book])              break;      } return book;}int main(){string a,b;cin>>a>>b;int a_size=a.size();int b_size=b.size();int Length=b.size()+1; /* 因为已知b>a,且相加可能会进一 */int *i_a=new int[Length];int *i_b=new int[Length];/* 初始化 */for (int i=0;i<Length;i++)               i_a[i]=i_b[i]=0;/* 逆序存储 */  for (int i=0;i<a_size;i++)   i_a[a_size-i-1]=a[i]-'0';          for (int i=0;i<b_size;i++)   i_b[b_size-i-1]=b[i]-'0'; /* 高精度减法,求出a~b之间有多少个数 */int sum=Hps(Length,i_a,i_b);int temp=Hpa(Length,i_a,0); /* 返回book */while(sum>=0){for(int i=temp;i>=0;i--){ans[i_a[i]]++;}sum--;temp=Hpa(Length,i_a,1); /* 加1 */}for(int i=0;i<=9;i++)cout<<ans[i]<<" ";return 0;}


1 0