1 条题解

  • 0
    @ 2025-8-24 21:15:42

    自动搬运

    查看原文

    来自洛谷,原作者为

    avatar zjh114514
    逸一时,误一世!

    搬运于2025-08-24 21:15:41,当前版本为作者最后更新于2023-11-13 21:40:16,作者可能在搬运后再次修改,您可在原文处查看最新版

    自动搬运只会搬运当前题目点赞数最高的题解,您可前往洛谷题解查看更多

    以下是正文


    观前提示:本题解建议已经有数位 dp 基础的谷民食用。如果不知道什么是数位 dp,请移步 P2602,那里有非常详细的数位 dp 解析。

    求回文数(加强版)题解

    题意

    给出一个正整数 nn,求 [1,n][1,n] 中回文数的个数对 2009111920091119 取模的值。
    n10100n≤10^{100}

    思路

    观察到 nn 很大,可以考虑数位 dp。
    简单思考可以发现,对于不足 nn 位的数,可以提前计算出回文数的个数。
    而对于 nn 位的数,可以采用暴力求回文数的做法,枚举回文数的一半得到整个回文数,并用记忆化搜索优化。

    代码

    #include<bits/stdc++.h>
    using namespace std;
    const int MAXN=105,MOD=20091119;
    char s[MAXN];
    int a[MAXN],len;
    int dp[2][MAXN];
    int temp[MAXN],total;
    int check(){
        for(int i=total,j=(len>>1)+(len&1);i&&j;i--,j--){//+(len&1)判断奇/偶回文数。
            if(temp[i]>a[j]) return 0;
            if(temp[i]<a[j]) return 1;
        }
        return 1;
    }
    int dfs(bool lim,int pos){//lim为1时代表前面高位的都和原数一样,pos为当前下标。
        if(pos==(len>>1)){//枚举到一半。
            if(!lim) return 1;//如果lim为0,后面可以随便取,返回1。
            return check();//否则判断一下是否超出原数,仅会判断1次。
        }
        if(~dp[lim][pos]) return dp[lim][pos];
        int res=0;
        for(int i=0;i<=9;i++){
            if(pos==len&&!i) continue;//最高位必不等0。
            if(lim&&i>a[pos]) break;//超出原数就终止循环。
            temp[++total]=i;//存下回文数的一半。
            res=(res+dfs(lim&&i==a[pos],pos-1))%MOD;
            total--;
        }
        return dp[lim][pos]=res;
    }
    int solve(){
        for(int i=1;i<=len;i++) a[i]=s[len-i+1]-48;//转成数字,a[1]为个位。
        int res=0;
        for(int i=len-1;i;i--){
            int res2=9;//避免前导零。
            for(int j=i-1;j>(i>>1);j--) res2=(res2*10)%MOD;
            res=(res+res2)%MOD;
        }
        //提前计算不足n位的数的回文数个数。
        memset(dp,-1,sizeof(dp));
        res=(res+dfs(1,len))%MOD;
        return res;
    }
    int main(){
        scanf("%s",s+1);
        len=strlen(s+1);
        printf("%d",solve());
        return 0;
    }
    
    • 1

    [信息与未来 2015] 求回文数(加强版)

    信息

    ID
    9165
    时间
    1000ms
    内存
    128MiB
    难度
    4
    标签
    递交数
    0
    已通过
    0
    上传者