zoukankan      html  css  js  c++  java
  • [Luogu] P3413 萌数

    题目背景

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

    寂月城网站是完美信息教室的官网。地址:已和谐 。

    题目描述

    辣鸡蒟蒻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。

    题目解析

    数位DP,难度一般

    因为数据比较水所以我先预处理出1~1000的萌数

    处理需要技巧,因为萌数有两种:相邻数相同和隔一个数相同,直接做会难以去重。所以我们搞一搞,用容斥就不需要去重了。

    dp[i][j][k] 表示第i位是j,第i-1位是k的萌数数量,进行数位dp即可。

    Code

    #include<bits/stdc++.h>
    using namespace std;
    
    const long long MAXN = 1000 + 5;
    const long long p = 1e9 + 7;
    
    long long dp[MAXN][10][10];
    //到第i位时,i位是j,i-1位是k,有多少不萌的数。
    long long ans;
    string l,r;
    
    long long find_ans(long long n,string s) {
        long long x = -1,y = -1;
        long long tot = 0,res = 0;
        bool flag = true;
        for(long long i = 0; i < n; i++) {
            tot = (tot * 10 + s[i] - '0') % p;
        }
        for(long long i = 1; i < n; i++) {
            for(long long j = 1; j <= 9; j++) {
                for(long long k = 0; k <= 9; k++) {
                    res = (res + dp[i][j][k]) % p;
                }
            }
        }
        if(n > 1) res += 10;
        for(long long i = n; i > 1; i--) {
            long long tmp = s[n - i] - '0';
            for(long long j = 0; j < tmp; j++) {
                if(i == n && j == 0) continue;
                for(long long k = 0; k <= 9; k++) {
                    if(x != j && y != j && j != k && k != x) {
                        res += dp[i][j][k];
                        res %= p;
                    }
                }
            }
            if(tmp == x||tmp == y) {
                flag = false;
                break;
            }
            y = x;
            x = tmp;
        }
        if(flag) {
            for(long long j = 0; j <= s[n - 1] - '0'; j++) {
                if(j != y && j != x) {
                    res++;
                    res %= p;
                }
            }
        }
        return (tot + 1 - res + p) % p;
    }
    
    int main() {
        cin >> l >> r;
        for(long long i = 2; i <= 1000; i++) {
            for(long long j = 0; j <= 9; j++) {
                for(long long k = 0; k <= 9; k++) {
                    if(j == k) continue;
                    for(long long l = 0; l <= 9; l++) {
                        if(j != l && k != l) dp[i][j][k] += dp[i - 1][k][l];
                    }
                    if(i == 2) dp[i][j][k]++;
                    dp[i][j][k] %= p;
                }
            }
        }
        ans = (long long)(find_ans(r.length(),r) - find_ans(l.length(),l)) % p;
        for(long long i = 1; i <= l.length(); i++) {
            if(l[i] == l[i - 1] || (i > 1 && l[i] == l[i - 2])) {
                ans++;
                ans %= (long long)p;
                break;
            }
        }
        printf("%lld",ans);
        return 0;
    }
  • 相关阅读:
    leetcode 673. 最长递增子序列的个数 java
    leetcode 148. 排序链表 java
    leetcode 98. 验证二叉搜索树 java
    leetcode 29. 两数相除 java
    leetcode 234. 回文链表 java
    Valid Palindrome LeetCode Java
    Single Number II LeetCode Java
    Single Number LeetCode java
    Search in Rotated Sorted Array II LeetCode Java
    Search in Rotated Sorted Array leetcode java
  • 原文地址:https://www.cnblogs.com/floatiy/p/9476986.html
Copyright © 2011-2022 走看看