zoukankan      html  css  js  c++  java
  • 【3006】统计数字

    统计数字

    Time Limit: 3 second
    Memory Limit: 2 MB

    【问题描述】

        一本书的页数为N,页码从1开始编起,请你求出全部页码中,用了多少个0、1、2、3、4、5、6、7、8、9。其中每个页码不含多余的0,如N=123时,第5页不是005,只是5,第12页不是012,只是12。

    【输入】

        输入文件仅一行,一个正整数N(N≤109),表示总的页码数。

    【输出】

        输出文件十行,第K行为数字k-1的个数,即第一行为数字0的个数,第二行为数字1的个数,第三行为数字2的个数,以此类推。

    【输入样例】

    11

    【输出样例】

    1
    4
    1
    1
    1
    1
    1
    1
    1
    1
     

    【题解】

    这题很恶心,没错 又是恶心这个词,以后只可能会越来越多地出现这个词。不会减少。。。

    我是看着题解写的程序。

    首先,从000-999 我们不要删掉多余的0,那么我们会有1000个3位数,然后一共有3000个数字出现过,可以想想0-9,每个数字都只出现一次,00-99,也可以知道0-9每个数字都出现相同的次数。推广一下,000-999每个数字出现的次数也是一样的。

    然后3000个数字,0-9有10个,则每个数字都有用到300次。

    先别问我0的事!

    然后我们举个例子。

    6147

    我们先看6,6之前有0-5,后3位,都从000-999变化,刚才我们算出来了,每个数字都会用到300次,0-5有6位,所以a[0..9]+=6*300;

    然后是0-5这6个数字作为第一位,每个都出现过1000次,即0XXX 1XXX 2XXX...其中XXX ∈ [000,999];

    最后是6,6我们要单独处理,要加上148,即6XXX,XXX∈[000..148];

    然后处理1,4,7就好。

    (这里你用while已经能写出来了,只要按照6的规律就可以)

    接下来是0的问题了。

    先从只有一位数的情况开始。

    比如6;

    我们先会看看6后面有没有数字,没有。

    然后看看6前面有没有数字,有。要加上几呢? 假设l是数字的长度,我们肯定会这样做的

    t = 1

    for (int i = 1; i<=l-1;i++)

      t = t *10;

    这里如果是上面说的6174,l=4,则t=1000;

    但是这里我们是以6为例,所以t = 1;

    然后for (int i = 0;i <=5;i++)

      a[i]+=t;

    这里已经多出来一个0了。

    剩下步骤省略。。

    対,如果一位数字会多出1个0;

    两位数。

    比如12

    我们先会看1后面有没有数字,有。

    那就用下我们上面的公式。

    0-9有10个一位数字。。。。然后每个数字被用一次。

    则a[0..9]+=1;

    //这里出现的0是多出的。

    然后是0 被用了 10 次 0-9,

    //这里的0也是多出来的。即00 01 02 03...09;

    这里出现了11个多余的0

    剩下步骤省略,因为没有出现多余的0.

    111

    1111

    即多出的0是数字的位数。

    【代码】

    #include <cstdio>
    #include <iostream>
    #include <string>
    
    using namespace std;
    
    string s1;
    unsigned int n;
    int a[10];
    
    void input_data()
    {
        cin >> s1;
    }
    
    void get_ans()
    {
        int l = s1.size(); //先获取数据的长度
        for (int i = 0;i <= 9;i++) //每个数字使用的数目初始化
            a[i] = 0;
        int t = 0;
        for (int i = 1;i <= l;i++) //先减去多余的0,即l(字母L)个1(数字1)
            t = t*10 + 1;
        a[0] -= t; //减去多余的0
        while (l > 0) //如果还能继续减少长度 基本上写出第一层第二层就不会有问题了。
            {
                int m = s1[0] - '0'; //先取出头数字
                t = 1;
                for (int i = 1;i <= l-1;i++) //这里是6174中 6时的1000
                    t = t * 10;
                int tt = (t * (l-1))/10; //000 - 999 中每个数字被使用的次数 while进行一次就变成00-99
                for (int i = 1;i <= m;i++) //0XXX 1XXX 2XXX 。。。。mXXX 中的 XXX
                    for (int j = 0;j <= 9;j++)
                        a[j] += tt;
                for (int i = 0;i <= m-1;i++) //0XXX 1XXX 2XXX ... mXXX中的 1..m
                    a[i] += t;
                s1 = s1.erase(0,1); //这是从
                int ttt =0;
                l = s1.size();
                for (int i = 0;i <l;i++)
                    ttt = ttt*10 + s1[i] - '0';
                ttt++;
                a[m] += ttt; //这是统计6147 中的148.
            }
    
    }
    
    void output_ans()
    {
        for (int i = 0 ;i <= 9;i++)
            printf("%d
    ",a[i]);
    }
    	
    
    int main()
    {
        input_data();
        get_ans();
        output_ans();
        return 0;
    }
    
  • 相关阅读:
    Android 中的通知
    Android 画图之Matrix(二)
    Android 画图之 Matrix(一)
    Android 实现书籍翻页效果(转载链接)
    Android 基于TranslateAnimation 的动画动态菜单(非系统menu菜单)
    Activity 页面切换的效果
    Android 访问本地API doc较慢
    Eclipse插件工具
    Android 性能优化的一些方法
    Android JAVA代码执行shell命令
  • 原文地址:https://www.cnblogs.com/AWCXV/p/7632451.html
Copyright © 2011-2022 走看看