• [LUOGU3413] SAC#1


    题目背景

    本题由世界上最蒟蒻最辣鸡最撒比的SOL提供。

    寂月城网站是完美信息教室的官网。地址:http://191.101.11.174/mgzd

    题目描述

    辣鸡蒟蒻SOL是一个傻逼,他居然觉得数很萌!

    好在在他眼里,并不是所有数都是萌的。只有满足“存在长度至少为2的回文子串”的数是萌的——也就是说,101是萌的,因为101本身就是一个回文数;110是萌的,因为包含回文子串11;但是102不是萌的,1201也不是萌的。

    现在SOL想知道从l到r的所有整数中有多少个萌数。

    由于答案可能很大,所以只需要输出答案对1000000007(10^9+7)的余数。

    输入输出格式

    输入格式:

    输入包含仅1行,包含两个整数:l、r。

    输出格式:

    输出仅1行,包含一个整数,即为答案。

    输入输出样例

    输入样例#1: 复制
    1 100
    输出样例#1: 复制
    10
    输入样例#2: 复制
    100 1000
    输出样例#2: 复制
    253

    说明

    记n为r在10进制下的位数。

    对于10%的数据,n <= 3。

    对于30%的数据,n <= 6。

    对于60%的数据,n <= 9。

    对于全部的数据,n <= 1000,l < r。


    随便写写

    f[i][j][k][0/1],决策到第i位,上一位的数字是j,上上位的数字是k,是否曾经出现过回文串, 的总数。

    然后就记忆化搜索一下,记得判断前一位和前前一位是否合法...


    #include <iostream>
    #include <cstdio>
    #include <cstring>
    using namespace std;
    #define int  long long
    inline int read() {
        int res=0;char ch=getchar();
        while(!isdigit(ch)) ch=getchar();
        while(isdigit(ch)) res=(res<<3)+(res<<1)+(ch^48), ch=getchar();
        return res;
    }
    #define reg register
    #define mod 1000000007
    int l, r;
    
    int f[1005][10][10][2];
    int wei[1005], cnt;
    
    inline int dp(int pos, int lst1, int lst2, bool hav, bool flag, bool fir, bool sec)
    {                                                 //是否有限制 
        if (pos == 0) return hav;
        if (!fir and !sec and !flag and f[pos][lst1][lst2][hav] != -1) return f[pos][lst1][lst2][hav] % mod;
        int lim = flag ? wei[pos] : 9;
        int ans = 0;
        for (reg int i = 0 ; i <= lim ; i ++)
        {
            if (i == lst1 and !fir) ans = (ans + dp(pos - 1, i, lst1, 1, flag && i == wei[pos], fir && i == 0, sec && lst1 == 0)) % mod;
            else if (i == lst2 and !fir and !sec) ans = (ans + dp(pos - 1, i, lst1, 1, flag && i == wei[pos], fir && i == 0, sec && lst1 == 0)) % mod;
            else ans = (ans + dp(pos-1, i, lst1, hav, flag && i == wei[pos], fir && i == 0, sec && lst1 == 0)) % mod;
        }
        if (!flag and !fir and !sec) f[pos][lst1][lst2][hav] = ans % mod;
        return ans % mod;
    }
    
    
    signed main()
    {
        memset(f, -1, sizeof f);
        int res1 = 0, res2 = 0;
        
        string a;
        cin >> a;
        cnt = 0;
        for (reg int i = a.length() - 1 ; i >= 0 ; i --) wei[++cnt] = a[i] - '0';
        int k = 1;
        if (wei[1]) wei[1]--;
        else {while(wei[k] == 0) wei[k] = 9, k++; wei[k]--;}
        
        res1 = dp(cnt, 0, 0, 0, 1, 1, 1) % mod;
        
        cnt = 0;
        cin >> a;
        for (reg int i = a.length() - 1 ; i >= 0 ; i --) wei[++cnt] = a[i] - '0';
        res2 = dp(cnt, 0, 0, 0, 1, 1, 1) % mod;
        
        printf("%lld
    ", (res2 - res1 + mod) % mod);
        return 0;
    }
  • 相关阅读:
    Educational Codeforces Round 104 (Rated for Div. 2) A B C D E
    Codeforces Round #701 (Div. 2) A B C D
    Codeforces Round #700 (Div. 2) A B C D1
    记录一次Boot整合Batch框架无法连接达梦数据库的问题
    关于Java中的volatile关键字的总结,适合了解不太多的人
    写个日志切面追踪,可以更直接查看项目执行的各种信息打印。
    sqlServer实现group by 之后 聚合操作之拼接结果
    SQL CURSOR 游标
    SQL case when
    Redis版本
  • 原文地址:https://www.cnblogs.com/BriMon/p/9476945.html
Copyright © 2020-2023  润新知