zoukankan      html  css  js  c++  java
  • 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;
    }
    
    
    



  • 相关阅读:
    redis发布订阅
    redis学习笔记(面试题)
    redis安全 (error) NOAUTH Authentication required
    HDU3001 Travelling —— 状压DP(三进制)
    POJ3616 Milking Time —— DP
    POJ3186 Treats for the Cows —— DP
    HDU1074 Doing Homework —— 状压DP
    POJ1661 Help Jimmy —— DP
    HDU1260 Tickets —— DP
    HDU1176 免费馅饼 —— DP
  • 原文地址:https://www.cnblogs.com/wyboooo/p/9643445.html
Copyright © 2011-2022 走看看