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;
    }
    
  • 相关阅读:
    错误提示窗口-“操作系统当前的配置不能运行此应用程序”
    打印机无法打印的10种解决方法
    开发进度三
    人月神话阅读笔记二
    开发进度二
    开发进度1
    人月神话阅读笔记一
    库存物资管理系统
    四则运算
    动手动脑5
  • 原文地址:https://www.cnblogs.com/fushao2yyj/p/9582344.html
Copyright © 2011-2022 走看看