zoukankan      html  css  js  c++  java
  • 12.2 NOIP 模拟 准考证号

    Description

    ([a,b]) 中有多少个不含 (37)(4) 的数字。

    (1 leq a, space b leq 2 imes 10^9)

    Solution

    很明显的一道数位 (mathrm{dp}) 啊。但是我太菜了,并不会数位 (mathrm{dp})

    再仔细一看:数位 (mathrm{dp}) 的数据范围咋开这么小啊,是不是想让打表水过啊。于是我们有了一个新的思路:打表。

    可以采用分块的思想,以 (10^7) 为一段,把每一段符合条件的数字个数都计算出来。这样一共有 (200) 段。制表代码如下:

    #include <iostream>
    #include <cstdio>
    #include <cstring>
    #include <algorithm>
    using namespace std;
    
    const int N = 2e9, unit = 5000000;
    int L, R, x, ans, p[23333];
    
    int solve(int l, int r)
    {
        p[0] = 0, ans = 0;
        for(int i = l; i <= r; i++)
        {
            int x = i, len = 0, fl = 1;
            while(x != 0) { p[++len] = x % 10; x /= 10; }
            for(int j = 1; j <= len; j++)
                if(p[j] == 4 || p[j] == 3 && p[j - 1] == 7)
                    fl = 0;
            ans += fl;
        }
        return ans;
    }
    
    int main()
    {
        freopen("dabiao.out", "w", stdout);
        for(int i = 1; i <= 400; i++)
        {
            L = unit * (i - 1) + 1, R = unit * i;
            printf("%d, ", solve(L, R));
        }
        return 0;
    }
    

    大概一两分钟就能跑出来。

    剩下的跟分块一样。扫描打出来的每一段,如果被 ([a,b]) 区间包含就直接统计答案。区间多余的两边暴力统计。时间复杂度大概是 (mathrm{O(200 + 2 imes 8 imes 10^7)}),极限数据在本地跑大概 (1.1s),可以通过。

    Code

    #include <iostream>
    #include <cstdio>
    #include <cstring>
    using namespace std;
    
    const int unit = 1e7;
    int biao[233] = {0, 4435929, 4435929, 4435929, 3936807, 1, 4435929, 4435929, 4435929, 4435929, 4435929, 4435929, 4435929, 4435929, 3936807, 1, 4435929, 4435929, 4435929, 4435929, 4435929, 4435929, 4435929, 4435929, 3936807, 1, 4435929, 4435929, 4435929, 4435929, 4435929, 4435929, 4435929, 4435929, 3936807, 1, 4435929, 4435928, 1, 4435929, 4435928, 0, 0, 0, 0, 0, 0, 0, 0, 0, 1, 4435929, 4435929, 4435929, 3936807, 1, 4435929, 4435929, 4435929, 4435929, 4435929, 4435929, 4435929, 4435929, 3936807, 1, 4435929, 4435929, 4435929, 4435929, 4435929, 4435929, 4435929, 4435929, 3936807, 1, 4435929, 4435929, 4435929, 4435929, 4435929, 4435929, 4435929, 4435929, 3936807, 1, 4435929, 4435929, 4435929, 4435929, 4435929, 4435929, 4435929, 4435929, 3936807, 1, 4435929, 4435929, 4435929, 4435929, 4435929, 4435929, 4435929, 4435929, 3936807, 1, 4435929, 4435929, 4435929, 4435929, 4435929, 4435929, 4435929, 4435929, 3936807, 1, 4435929, 4435929, 4435929, 4435929, 4435929, 4435929, 4435929, 4435929, 3936807, 1, 4435929, 4435929, 4435929, 4435929, 4435929, 4435929, 4435929, 4435929, 3936807, 1, 4435929, 4435928, 1, 4435929, 4435928, 0, 0, 0, 0, 0, 0, 0, 0, 0, 1, 4435929, 4435929, 4435929, 3936807, 1, 4435929, 4435929, 4435929, 4435929, 4435929, 4435929, 4435929, 4435929, 3936807, 1, 4435929, 4435929, 4435929, 4435929, 4435929, 4435929, 4435929, 4435929, 3936807, 1, 4435929, 4435929, 4435929, 4435929, 4435929, 4435929, 4435929, 4435929, 3936807, 1, 4435929, 4435929, 4435929, 4435929, 4435929, 4435929, 4435929, 4435929, 3936807, 1, 4435929, 4435929, 4435929, 4435929, 4435929};
    int a, b, L, R, res, flg = 0, p[2333], lx = 0x3f3f3f3f, rx = 0, ans = 0;
    
    inline int solve(int l, int r)
    {
        p[0] = 0, res = 0;
        for(int i = l; i <= r; i++)
        {
            int x = i, len = 0, fl = 1;
            while(x != 0) { p[++len] = x % 10; x /= 10; }
            for(int j = 1; j <= len; j++)
                if(p[j] == 4 || p[j] == 3 && p[j - 1] == 7)
                    fl = 0;
            res += fl;
        }
        return res;
    }
    
    int main()
    {
        scanf("%d%d", &a, &b);
        for(int i = 1; i <= 200; i++)
        {
            L = unit * (i - 1) + 1, R = unit * i;
            if(a <= L && b >= R)
            {
                flg = 1;
                lx = min(lx, L);
                rx = max(rx, R);
                ans += biao[i];
            }
            if(L > b) break;
        }
        if(flg && lx > a) ans += solve(a, lx - 1);
        if(flg && rx < b) ans += solve(rx + 1, b);
        if(!flg) ans = solve(a, b);
        printf("%d", ans);
        return 0;
    }
    
  • 相关阅读:
    微信小程序实现运动步数排行(可删除)
    微信小程序实现运动步数排行(可删除)
    一个文艺的在线生成漂亮的二维码工具网站
    微信小程序常见的UI框架/组件库总结
    天天快车是款精细的游戏
    MHA的几种死法-叶良辰
    编译maxscale
    mydbtest文档
    高山仰止
    docker居然需要3.10以上的内核
  • 原文地址:https://www.cnblogs.com/Andy-park/p/14085007.html
Copyright © 2011-2022 走看看