• 51nod 1042数字0-9的数量




    基准时间限制:1 秒 空间限制:131072 KB 分值: 10 难度:2级算法题
     收藏
     关注
    给出一段区间a-b,统计这个区间内0-9出现的次数。
    比如 10-19,1出现11次(10,11,12,13,14,15,16,17,18,19,其中11包括2个1),其余数字各出现1次。
    Input
    两个数a,b(1 <= a <= b <= 10^18)
    Output
    输出共10行,分别是0-9出现的次数
    Input示例
    10 19
    Output示例
    1
    11
    1
    1
    1
    1
    1
    1
    1
    1

    没什么思路 看了题解前半部分 说跟51nod上一道问1的个数的题很像

    题目在这里

    基准时间限制:1 秒 空间限制:131072 KB 分值: 5 难度:1级算法题
     收藏
     关注
    给定一个十进制正整数N,写下从1开始,到N的所有正数,计算出其中出现所有1的个数。
    例如:n = 12,包含了5个1。1,10,12共包含3个1,11包含2个1,总共5个1。
    Input
    输入N(1 <= N <= 10^9)
    Output
    输出包含1的个数
    Input示例
    12
    Output示例
    5

    感觉思路真的挺巧妙的 统计各个位数是1的数

    比如:12。个位上可能出现1的数为1,11(一共2个),十位上可能出现1的个数为10,11,12(一共3个),加一起正好是5。(至于11是否重复的问题,还是再理解一下上面的做法,这个做法只考虑了每一位出现1的数,11在个位上算和在十位上算是不一样的,所以并没有重复)。

    21905:

    个位:它出现1的数为:1 ~ 21901,一共 2190 - 0 + 1 = 2191

    十位:它出现1的数为:1x ~ 2181x (x 从0到9)一共:(218 - 0 + 1)*10 = 2190

    百位:它出现1的数为:1xx ~ 211xx ,一共:(21 - 0 + 1)* 100 = 2200

    千位:它出现1的数为:1xxx ~ 11xxx 和 21000 ~ 21905 ,那么很明显,这个情况就比较特殊了,为什么呢?下面再说,我们先计数,一共:(1 - 0 + 1)*1000 + (905 - 0 + 1)= 2000 + 906 = 2906

    万位:它出现1的数为:1xxxx ~ 1xxxx,一共:10000


    那么现在这道题相当于就是把1009的代码改一下,不仅仅是看1了
    把1到a-1的统计一下 1到b的统计一下 相减就是结果了
    但是写了以后发现还有问题 因为0比较特殊 不能作为分母 也不能用来取模
    改了半天 发现还是得重新写一个针对0的函数
    #include <iostream>
    #include <cstdio>
    #include <algorithm>
    #include <string.h>
    #include <cstring>
    #include <cmath>
    #define inf 0x3f3f3f3f
    #define ll long long
    using namespace std;
    
    ll a, b;
    ll ansa[10], ansb[10];
    
    ll cntnum(int num, ll n)
    {
        ll ans = 0, tmp = n;
        long long tnum = 1;
        while(tmp){
            long long t = tmp % 10;
            if(t < num && num){
                ans += n / (tnum * 10) * tnum;
            }
            else if(t == num){
                if(num){
                    ans += n / (tnum * 10) * tnum;
                    ans += (n % tnum) + 1;
                }
                else ans++;
            }
            else{
                if(num)ans += (n / (tnum * 10) + 1) * tnum;
                else ans++;
            }
    
            tnum *= 10;
            tmp /= 10;
        }
    
        return ans;
    }
    
    ll cnt0(ll n)
    {
        ll i = 1;
        ll ans = 0;
        ll before = 0, cur = 0, after = 0;
        while((n / i)){
            cur = (n / i) % 10;
            before = n / (i * 10);
            after = n - (before * 10 + cur) * i;
            if(cur == 0){
                ans += (before - 1) * i + after + 1;
            }
            else{
                ans += before * i;
            }
            i *= 10;
        }
        return ans;
    }
    
    int main()
    {
        while(scanf("%I64d%I64d", &a, &b) != EOF){
            memset(ansa, 0, sizeof(ansa));
            memset(ansb, 0, sizeof(ansb));
            ansa[0] = cnt0(a - 1);
            ansb[0] = cnt0(b);
            for(int i = 1; i <= 9; i++){
                ansa[i] = cntnum(i, a - 1);
                ansb[i] = cntnum(i, b);
                //cout<< ansb[i] - ansa[i]<<endl;
            }
            /*while(a){
                ansa[a % 10]--;
                a /= 10;
            }*/
    
            for(int i = 0; i <= 9; i++){
                cout<< ansb[i] - ansa[i]<<endl;
            }
    
        }
        return 0;
    }
    
    
    

    新改的这份代码应该会更容易理解一点
    #include <iostream>
    #include <cstdio>
    #include <algorithm>
    #include <string.h>
    #include <cstring>
    #include <cmath>
    #define inf 0x3f3f3f3f
    #define ll long long
    using namespace std;
    
    ll a, b;
    ll ansa[10], ansb[10];
    
    /*ll cntnum(int num, ll n)
    {
        ll ans = 0, tmp = n;
        long long tnum = 1;
        while(tmp){
            long long t = tmp % 10;
            if(t < num){
                ans += n / (tnum * 10) * tnum;
            }
            else if(t == num){
                ans += n / (tnum * 10) * tnum;
                ans += (n % tnum) + 1;
            }
            else{
                ans += (n / (tnum * 10) + 1) * tnum;
            }
    
            tnum *= 10;
            tmp /= 10;
        }
    
        return ans;
    }*/
    
    ll cnt0(ll n)
    {
        ll i = 1;
        ll ans = 0;
        ll before = 0, cur = 0, after = 0;
        while((n / i)){
            cur = (n / i) % 10;
            before = n / (i * 10);
            after = n - (before * 10 + cur) * i;
            if(cur == 0){
                ans += (before - 1) * i + after + 1;
            }
            else{
                ans += before * i;
            }
            i *= 10;
        }
        return ans;
    }
    
    ll cntnum(int num, ll n)
    {
        ll i = 1;
        ll ans = 0;
        ll before = 0, cur = 0, after = 0;
        while((n / i)){
            cur = (n / i) % 10;
            before = n / (i * 10);
            after = n - (before * 10 + cur) * i;
            if(cur == num){
                ans += before * i + after + 1;
            }
            else if(cur < num){
                ans += before * i;
            }
            else{
                ans += (before + 1) * i;
            }
            i *= 10;
        }
        return ans;
    }
    int main()
    {
        while(scanf("%I64d%I64d", &a, &b) != EOF){
            memset(ansa, 0, sizeof(ansa));
            memset(ansb, 0, sizeof(ansb));
            ansa[0] = cnt0(a - 1);
            ansb[0] = cnt0(b);
            for(int i = 1; i <= 9; i++){
                ansa[i] = cntnum(i, a - 1);
                ansb[i] = cntnum(i, b);
                //cout<< ansb[i] - ansa[i]<<endl;
            }
            /*while(a){
                ansa[a % 10]--;
                a /= 10;
            }*/
    
            for(int i = 0; i <= 9; i++){
                cout<< ansb[i] - ansa[i]<<endl;
            }
    
        }
        return 0;
    }
    
    
    



  • 相关阅读:
    C# 网络斗地主源码开源
    windows 10
    JAVA Eclipse Incorrect line ending found carriage return 怎么办
    JAVA Eclipse中如何简易的实现消息机制
    JAVA Eclipse中的Android程序如何使用线程
    JAVA Eclipse如何重新设置工作空间workspace
    JAVA Eclipse如何重命名包
    JAVA Eclipse如何修改Android程序名称
    JAVA Eclipse如何设置编程环境字体
    JAVA Eclipse如何设置点击按钮切换图片
  • 原文地址:https://www.cnblogs.com/wyboooo/p/9643445.html
Copyright © 2020-2023  润新知