zoukankan      html  css  js  c++  java
  • 洛谷 P2602 [ZJOI2010]数字计数

    洛谷

    第一次找规律A了一道紫题,写篇博客纪念一下。

    这题很明显是数位dp,但是身为蒟蒻我不会呀,于是就像分块打表水过去。

    数据范围是(10^{12}),我就(10^6)一百万一百万的打表。

    于是我就发现了一些规律。

    先献给大家一个打表程序吧~

    #include <bits/stdc++.h>
    using namespace std;
    
    int main()
    {
        long long l,r,cnt[10]={};
        for (long long t=0;t<=999999;++t) {
            l=t*1000000+1;
            r=(t+1)*1000000;
            for (long long i=l;i<=r;++i) {
                long long n=i;
                while (n) ++cnt[n%10],n/=10;
            }
            for (long long i=0;i<=9;++i) cout<<cnt[i]<<' ';
            cout<<endl;
        }
        return 0;
    }
    

    这是1~1000000,1000001~2000000,2000001~3000000……的表。

    也看一下吧。

    488895 600001 600000 600000 600000 600000 600000 600000 600000 600000 
    1088895 2200000 1200001 1200000 1200000 1200000 1200000 1200000 1200000 1200000 
    1688895 2800000 2800000 1800001 1800000 1800000 1800000 1800000 1800000 1800000 
    2288895 3400000 3400000 3400000 2400001 2400000 2400000 2400000 2400000 2400000 
    2888895 4000000 4000000 4000000 4000000 3000001 3000000 3000000 3000000 3000000 
    3488895 4600000 4600000 4600000 4600000 4600000 3600001 3600000 3600000 3600000 
    4088895 5200000 5200000 5200000 5200000 5200000 5200000 4200001 4200000 4200000 
    4688895 5800000 5800000 5800000 5800000 5800000 5800000 5800000 4800001 4800000 
    5288895 6400000 6400000 6400000 6400000 6400000 6400000 6400000 6400000 5400001 
    5888896 7000001 7000000 7000000 7000000 7000000 7000000 7000000 7000000 7000000 
    7488895 8600002 7600000 7600000 7600000 7600000 7600000 7600000 7600000 7600000 
    8088895 11200001 8200001 8200000 8200000 8200000 8200000 8200000 8200000 8200000 
    8688895 12800001 9800000 8800001 8800000 8800000 8800000 8800000 8800000 8800000
    

    这时候你会发现两个规律:

    • 每隔一百万,各个数字都会增加600000个,很神奇。
    • 对于当前的数字i,如果(frac{i}{10^k}>0(5<k<13)),那么(cnt[(frac{i}{10^k})~ exttt{mod}~10]+=1000000)

    有了这两大规律,我们就可以轻松处理出(10^{12})的大数据了。

    复杂度约为(O(frac{r-l+1}{1000000}))

    代码在下面:

    #include <bits/stdc++.h>
    using namespace std;
    int main()
    {
        long long a[10]={};
        long long l,r;cin>>l>>r;
        while (l<r&&l%1000000) {
            long long t=l;
            while (t) ++a[t%10],t/=10;
            ++l;
        }
        while (r>l&&r%1000000) {
            long long t=r;
            while (t) ++a[t%10],t/=10;
            --r;
        }
        while (l!=r) {
            for (int i=0;i<10;++i)
                a[i]+=600000;
            long long t=1000000;
            while (l/t&&t<=1000000000000) {
                a[l/t%10]+=1000000;
                t*=10;
            }
            l+=1000000;
        }
        while (r) ++a[r%10],r/=10;
        for (int i=0;i<10;++i) cout<<a[i]<<' ';
        return 0;
    }
    
  • 相关阅读:
    有价值的终会被人发现和承认
    Sql中存在斜杠“/”怎么办?
    JSONObject和JSONArray(json-lib-2.4)的基本用法
    如何设定linux系统时间
    动态创建的文本框想要加上jQuery的datepicker功能变成日期选择控件该怎么办?
    如果$.ajax函数迟迟得不到响应,那么最有可能出错的地方是请求参数写错了
    Notepad2替代系统自带的记事本Notepad
    css属性与js中style对象的属性对应表
    day02_js学习笔记_01_js的简介、js的基本语法
    Eclipse/MyEclipse的快捷键以及文档注释、多行注释的快捷键
  • 原文地址:https://www.cnblogs.com/fushao2yyj/p/9582344.html
Copyright © 2011-2022 走看看