zoukankan      html  css  js  c++  java
  • 清北学堂模拟赛d6t3 反击数

    分析:显然是一道数位dp题,不过需要一些奇怪的姿势.常规的数位dp能统计出一个区间内满足条件的数的个数,可是我们要求第k个,怎么办呢?转化为经典的二分问题,我们二分当前数的大小,看它是第几大的,就可以了.

          显然数位dp套上模板,再用上kmp的next数组就可以了,传递4个参数:还剩下多少位没有匹配,匹配了多少位,是否达到上限和是否匹配成功,到最后判断一下就可以了.

    学到了一种很强的思想:如果能求出i是第几个数,要求出第k个数就可以二分i的值.

    #include <cstdio>
    #include <cstring>
    #include <iostream>
    #include <algorithm>
    
    using namespace std;
    
    long long L, R, K, f[20][2010][2];
    int m, nextt[40], a[30];
    char X[100];
    
    void init()
    {
        nextt[0] = 0;
        nextt[1] = 0;
        for (int i = 1; i < m; i++)
        {
            int j = nextt[i];
            while (j && X[i] != X[j])
                j = nextt[j];
            nextt[i + 1] = X[i] == X[j] ? j + 1 : 0;
        }
    }
    
    long long dfs(int len, int w, bool limit, bool flag)
    {
        if (len == 0)
            return flag;
        if (!limit && f[len][w][flag] != -1)
            return f[len][w][flag];
        int maxn = limit ? a[len] : 9;
        long long cnt = 0;
        for (int i = 0; i <= maxn; i++)
        {
            int t = w;
            while (t && X[t] - '0' != i)
                t = nextt[t];
            if (X[t] - '0' == i)
                t++;
            cnt += dfs(len - 1, t, limit && (i == a[len]), flag || (t == m));
        }
        return limit ? cnt : f[len][w][flag] = cnt;
    }
    
    long long query(long long u)
    {
        int cnt = 0;
        while (u)
        {
            a[++cnt] = u % 10;
            u /= 10;
        }
        memset(f, -1, sizeof(f));
        return dfs(cnt, 0, 1, 0);
    }
    
    int main()
    {
        scanf("%lld %lld %s %lld", &L, &R, X, &K);
        m = strlen(X);
        init();
        if (query(R) < K + query(L - 1))
        {
            printf("Hey,wake up!
    ");
            return 0;
        }
        long long t = query(L - 1),ans = L;
        long long l = L, r = R;
        while (l < r)
        {
            long long mid = (l + r) >> 1;
            if (query(mid) - t >= K)
            {
                r = mid;
                ans = mid;
            }
            else
                l = mid + 1;
        }
        printf("%lld
    ", r);
    
        return 0;
    }
  • 相关阅读:
    python之Queue
    rebase after merge
    Heroku使用note
    Adapter, Proxy, Decrator, and AOP
    How rackup works
    sonar插件实战
    2012rubyconfchina小记
    Sonar安装使用篇
    sonar原理扩展篇
    javascript 实现拖动效果
  • 原文地址:https://www.cnblogs.com/zbtrs/p/7633376.html
Copyright © 2011-2022 走看看