• 【POJ2282 The Counting Problem】求区间[a,b]中每个数字出现的次数


    题目链接:http://poj.org/problem?id=2282

    题目大意:给你两个数a,b,让你计算a到b之间所有的数总共包含多少0~9。

    解题思路:  蛋疼的人生蛋疼的题。可以分别统计[0,b]中包含多少个0~9,[0,a]中包含多少个0~9,两个求得的结果相减就是答案了。

             举例分析: 299 百位数字有0,1,2,那么它们在百位时分别出现了100次,再对十位数和个位数的99分析,因为[0,99]中0~9出现的频率都是一样的,

    分别为2(前一个数的值)*(位数)*10(固定一个数其余位能变化的次数)。

             所以对于4567,我们可以这样拆:0~3999,4000~4499,4500~4559,~4560~4567 。求得得总和就是答案了,还要注意一点的是前导0不能加进去,注意把加进去多余的前导0减掉。

    View Code
     1 #include <iostream>
     2 #include <cstdio>
     3 #include <cstring>
     4 #include <sstream>
     5 #include <algorithm>
     6 using namespace std;
     7 
     8 void Cal(string s, int *num)
     9 {
    10     int k=1;
    11     for(int i=0; i<s.size()-1; i++)
    12        k*=10, num[0]-=k;
    13     for(int i=0; i<s.size(); i++,k/=10)
    14     {
    15         for(int j=0; j<s[i]-'0'; j++)
    16             num[j]+=k;
    17         for(int j=0; j<10; j++)
    18             num[j]+=k/10*(s.size()-i-1)*(s[i]-'0'); ///!!这里要注意对于0~2999,[0,999]不仅要乘以位数还要乘以他前一位的值,指出现了多少次[0,999]
    19         for(int j=0; j<i; j++)
    20             num[s[j]-'0']+=(s[i]-'0')*k;  
    21         num[s[i]-'0']++;  ///末尾都是0的情况
    22     }
    23 }
    24 
    25 int main()
    26 {
    27     int n, m;
    28     string s;
    29     int a[10], b[10];
    30     while(~scanf("%d%d",&n,&m),n+m)
    31     {
    32         memset(a,0,sizeof(a));
    33         memset(b,0,sizeof(b));
    34         stringstream sa, sb;   ///中间过度函数,将int,double之类的类型转换成string
    35         if(n>m) swap(n,m);
    36         sa << n-1;
    37         s=sa.str();  
    38         Cal(s,a);
    39         sb<<m;
    40         s=sb.str();
    41         Cal(s,b);
    42         for(int i=0; i<10; i++)
    43         {
    44             if(i!=9) printf("%d ",b[i]-a[i]);
    45             else printf("%d\n",b[i]-a[i]);
    46         }
    47     }
    48     return 0;
    49 }

    补充解释

     1 #include <iostream>
     2 #include <sstream>
     3 #include <cstring>
     4 using  namespace std;
     5 
     6 ///以3456分析,3456可以划分为0~2999,3000~3399,3400~3449,3450~3456
     7 void Cal(string s, int* num)
     8 {
     9     int k=1;
    10     for(int i=0; i<s.size(); i++)
    11         k*=10, num[0]-=k;              ///去除去0作为前导的情况
    12     for(int i=0; i<s.size(); i++, k/=10)
    13     {
    14         for(int j=0; j<s[i]-'0'; j++)  ///第i位时,对最高位进行分析,比如0~2999,最高位0和1都出现了1000次。
    15             num[j]+=k;
    16         for(int j=0; j<10; j++)  ///对0~2999分析,[0,999]中0~9出现的概率一样,最高位大小(2)*位数(3)*固定一位的最多次数(100)
    17             num[j]+=(s[i]-'0')*(s.size()-i-1)*k/10;
    18         for(int j=0; j<i; j++)    ///对于前面的每一位,还要后续处理后面没处理到的情况,比如处理最高位3时只处理了0~2999,而没有处理3000~3399,3400~3449,3450~3456等情况,后面处理的时候要考虑到
    19             num[ s[j]-'0' ]+=(s[i]-'0')*k;
    20         num[ s[i]-'0' ]++;  ///末尾都是0的情况
    21     }
    22 }
    23 
    24 int main()
    25 {
    26     int n;
    27     int num[10];
    28     while(cin >> n)
    29     {
    30         stringstream sa;
    31         memset(num,0,sizeof(num));
    32         string str;
    33         sa << n;
    34         sa >> str;
    35         Cal(str,num);
    36         for(int i=0; i<10; i++)
    37             cout << num[i] <<endl;
    38     }
    39 }
    View Code
  • 相关阅读:
    iOS开发UI篇—Quartz2D使用(图片剪切)
    LeanCloud存取数据
    Pod搜不到类库解决办法
    第三方的工具以及插件
    苹果开发账号申请注意事项
    苹果账号网址汇总
    代码规范
    流媒体
    iOS面试题
    安装 Alcatraz
  • 原文地址:https://www.cnblogs.com/kane0526/p/3011038.html
Copyright © 2020-2023  润新知