• 计数问题


    计数问题

    TimeLimit: 1 Second   MemoryLimit: 32 Megabyte

    Totalsubmit: 1712   Accepted: 193  

    Description

    给你两个数a和b,你的任务是计算出1在a和b之间出现的次数,比如说,如果a=1024,b=1032,那么a和b之间的数就是:

    1024 1025 1026 1027 1028 1029 1030 1031 1032

    则有10个1出现在这些数中。

    Input

    输入不会超过500行。每一行有两个数a和b,a和b的范围是0 < a, b < 100000000。输入两个0时程序结束,两个0不作为输入样例。

    Output

    对于每一对输入的a和b,输出一个数,代表1出现的个数。

    Sample Input


    1 10
    44 497
    346 542
    1199 1748
    1496 1403
    1004 503
    1714 190
    1317 854
    1976 494
    1001 1960
    0 0

    Sample Output

    2
    185
    40
    666
    113
    105
    1133
    512
    1375
    1256

     解题思路

      本题可以先求1在0~a之间出现的次数,再求出1在0~b-1之间出现的次数,相减即可。

    将0~197的数列出来后可以看出规律:
      ①可以求出1在190~197之间出现的次数,然后对于0~180.190~197中1在个位数上出现了1次。

      ②个位考虑完以后,直接考虑197/10-1(即18)中1出现的次数,同时考虑数字减小了,每一位的权值会增加,也就是说一个数字出现的次数会增加10倍。

    View Code
    /*本算法算出了0~9在a和b之间分别出现的次数,取答案时直接取d[1]即可*/
    #include <iostream>
    using namespace std;
    /*****************************************************************/
    const int N = 11;
    int d[N];         //d[N]存储0~9分别出现的次数
    int value;        //记录相应权值的变化
    void deal(int n);
    /****************************************************************/
    
    void deal(int n)
    {
        if ( n <= 0 )
        {
            return ;
        }
        int one, ten;
        one = n % 10;  //one,tenden别代表个位和十位
        n /= 10;
        ten = n;
        for ( int i = 0; i <= one; i++ )//将个位上出现的数统计下来
        {
            d[i] += value;
        }
        while ( ten )//十位上的数在one的前提下出现的次数
        {
            d[ten % 10] += (one + 1) * value;
            ten /= 10;
        }
        for ( i = 0; i < 10; i++ )//根据权值统计0~9出现的次数
        {
            d[i] += value * n;
        }
        d[0] -= value;//将第一位是0的情况排除
        value *= 10;//权值变化10倍
        deal (n-1);
    }
    
    int main()
    {
        int a, b;
        while ( cin >> a >> b)
        {
            if ( a == 0 && b== 0)
            {
                break;
            }            
            if ( a < b)
            {
                int tmp = b;
                b = a;
                a = tmp;
            }
            for (int i = 0; i < 10; i++)
            {
                d[i] = 0;
            }
            value  =1;
            deal(a);
            value = -1;//此处value=-1是为了求出最后的答案deal(a)-deal(b)
            deal(b - 1);
            cout << d[1]<< endl;
        }
        system ("pause");
        return 0;
    }
  • 相关阅读:
    HDU 1509 Windows Message Queue
    sql批量更换dedecms文章来源和作者
    dedecms织梦网站时间标签strftime和MyDate解析
    JS代码站原创DEDECMS教程插件系列
    DEDECMS织梦自定义表单中必填项、电话邮箱过滤以及验证码规则
    dedecms标签(tags)页面伪静态设置
    dedecms几个小技巧
    dedecms 5.7 网站搬家后产生的问题记录
    dedecms织梦做中英文(多语言)网站步骤详解
    DedeCMS系统设置说明:站点设置
  • 原文地址:https://www.cnblogs.com/libao/p/2451334.html
Copyright © 2020-2023  润新知