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

题意

找出\([1,n]\)回文数字

思路

数位dp

我们在dfs过程中需要知道哪里是回文中点 , 设\(h\)\(n\)的位数 , 回文中点为\(center\) , 一般而言为\(center = h/2\)

注意\(center\)的值 , 如果是奇数个 , 那么有\(aba\) , \(b可以取值0-9\) , 所以\(center\)\(h>>1\)才行(好像说了句废话)

但是如果有各种前导零的话 , 那就\(h\)就会随着前导零个数增加而较少 , 进而成为变量

所以可以提前处理出位数小于\(h\)的所有点

回文串的特点在于 ,如果前半段确定 , 那么后半也是确定的

对于没有limit的dfs来说 , 就是 \(1\) , 而对有有\(limit\)的dfs(实际上只有一个) , 单独判断一下就好

这是我见过的第一道不在\(!pos\)时终止的数位dp

代码

#include<bits/stdc++.h>
using namespace std;
#define int long long int

inline int read() {
    int ans = 0, f = 1;
    char ch = getchar();
    while (ch < '0' || ch > '9') {
        if (ch == '-')f = -1;
        ch = getchar();
    }
    while (ch <= '9' && ch >= '0') {
        ans = ans * 10 + ch - '0';
        ch = getchar();
    }
    return ans * f;
}
int a[110];
int cnt = 0;
int f[110];
const int mod = 20091119;
int dfs(int pos,int center,bool limit) {
    if (pos == center) {
        return !limit;
    }
    if (!limit && ~f[pos])
        return f[pos];
    int up = limit?a[pos]:9;
    int down = pos==cnt?1:0;
    int ans = 0;
    for (int i = down; i<= up; i++) {
        ans = (ans + dfs(pos-1,center,limit&&i==up)) % mod;
    }
    if (!limit) f[pos] = ans;
    return ans;
}
int qpow(int a,int b) {
    int ans = 1;
    while (b) {
        if (b&1)ans = (ans * a)%mod;
        a = (a*a)%mod;
        b>>=1;
    }
    return ans;
}
int work(string x) {
    for (auto e : x) {
        a[++cnt] = e-'0';
    }
    int res = 0;
    for (int i = 1; i<= cnt-1; i++) {
        int mid = i+1>>1;
        res = (res + qpow(10,mid) - qpow(10,mid-1)) %mod;
    }
    reverse(a+1,a+1+cnt);
    return (dfs(cnt,cnt>>1,true) + res) % mod;
}
signed main() {
    memset(f,-1,sizeof f);
    string n;
    cin>>n;
    int mid = n.size()/2 -1;
    string left = string(n.begin(),n.begin() + mid+1);
    string right = string((n.size()&1)?n.begin()+mid+2:n.begin()+mid+1,n.end());
    reverse(left.begin(),left.end());
    int ans = work(n) + (left <= right);
    cout<<ans % mod;
    return 0;
}

posted @ 2025-05-12 22:59  Guaninf  阅读(31)  评论(0)    收藏  举报