• SAC#1


    题意

    求[l,r]中存在回文子串的数的个数。答案对1e9+7取模。

    n<=1e1000

    题解

    这道题想不到正解的思路就很麻烦,看到题解就打开了新世界;

    完美的利用了回文串的性质,如果是偶数回文串,那么就肯定有一个长度为2的回文串,那么就有一个数位等于前一位;同理奇数回文串就有一个数位等于前前一位。

    因为题目只要出现回文串,没关注长度,所以只要关注这两个就可以了。

    其实很想挺简单,可能是自己积累太少了没想到。

    不过当时是真的觉得这是我做到的最妙的题。(2019.5.24 00:23:40)

    那么状态就很简单了,f[pos][pre][ppre][opy][lim],opt为是否出现回文串。

    #include<bits/stdc++.h>
    using namespace std;
    const int mod=1000000007;
    #define ll long long
    //只要有一个数等于它前一个或前前一个数就是萌数 
    char l[1005],r[1005];
    int len,num[1005];
    ll f[1005][11][11][2][2];
    
    ll dfs(int s,int pre,int ppre,bool opt,bool lim){
        if(!s) return opt;
        if(f[s][pre][ppre][opt][lim]!=-1) return f[s][pre][ppre][opt][lim];
        int mx=lim?num[s]:9;
        ll temp=0;
        for(int i=0;i<=mx;i++){
            temp=(temp+dfs(s-1,(pre==10&&i==0)?10:i,pre,opt||i==pre||i==ppre,lim&&i==mx))%mod;
        }
        return f[s][pre][ppre][opt][lim]=temp%mod;
    }
    
    ll cx(){
        memset(f,-1,sizeof(f));
        len=strlen(l+1);
        for(int i=1;i<=len;i++) num[i]=l[len-i+1]-'0';
        num[1]--;
        for(int i=1;i<=len;i++){
            if(num[i]>=0) break;
            num[i]+=10;num[i+1]--;
        }
        if(!num[len]) len--;
        ll temp1=dfs(len,10,10,false,true);
        memset(f,-1,sizeof(f));
        len=strlen(r+1);
        for(int i=1;i<=len;i++) num[i]=r[len-i+1]-'0';
        ll temp2=dfs(len,10,10,false,true);
        return temp2-temp1;
    }
    int main(){
        scanf("%s%s",l+1,r+1);
        printf("%lld",(cx()%mod+mod)%mod);
    }
    View Code
  • 相关阅读:
    用C#实现在线升级
    wordwrap,wordbreak,whitespace,textoverflow的区别和用法[转]
    Sql Server 存储过程分页大全(2005,2000)
    C#中生成中文繁体web页面
    如何在c#里执行sql server DTS包
    asp.net采集函数(采集、分析、替换、入库)
    css定义一个导航栏
    mssql与access的sql语法差异
    [转]sql server数据库定时自动备份
    HttpHandler与图片盗链
  • 原文地址:https://www.cnblogs.com/sto324/p/11266655.html
Copyright © 2020-2023  润新知