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;
    }
    
  • 相关阅读:
    spring
    google-c-style
    process想停就停,真爽
    mytop
    Java 图片设置圆角(设置边框,旁白)
    当setTimeout遇到闭包
    FreeMarker辅助
    ImageIO.wtrie生成jpg图片质量损失方案:BufferedImage生成jpg图片文件流
    从BufferedImage到InputStream,实现绘图后进行下载(生成二维码图片并下载)
    使用Javascript 实现类
  • 原文地址:https://www.cnblogs.com/fushao2yyj/p/9582344.html
Copyright © 2011-2022 走看看