数位dp 求l-r(10进制) 在k进制中有多少个回文数的模板

这是一个关于计算指定10进制数l到r在k进制中回文数数量的C++代码实现。通过深度优先搜索(dfs)函数,递归地确定每个数位的可能性,并利用动态规划(dp)存储中间结果,以提高效率。代码中定义了gao函数来计算给定数字在特定进制下的回文数个数。

摘要生成于 C知道 ,由 DeepSeek-R1 满血版支持, 前往体验 >

#include <cstdio>
#include <cstring>
#include <algorithm>
#include <iostream>
using namespace std;
#define LL long long
LL l, r;
int a[66];
LL dp[66][66][40];
LL dfs(int len, int l, int r, bool lim, bool ok,int k)//ok表示是回文串,k表示k进制
{


    if(l < r) return !lim || (lim && ok);
    if(!lim && ~dp[len][l][k]) return dp[len][l][k];
    LL ret = 0;
    int m = lim ? a[l] : (k-1);
    int i;
    for(i = 0; i <= m; i++)
    {
        if(l == len-1 && !i) continue;
        int g = ok;
        if(g) g = a[r] >= i;
        else g = a[r] > i;
        ret += dfs(len, l-1, r+1, lim&&i==m, g,k);
    }
    if(!lim) dp[len][l][k] = ret;
    return ret;
}


LL gao(LL n,int k)//n为数字,k为进制
{
    if(n < 0) return 0;
    if(n == 0) return 1;
    int len = 0;
    while(n) { a[len++] = n%k; n /= k; }
    LL ret = 1;
    int i;
    for(i = len; i >= 1; i--)//遍历回文数的长度
        ret += dfs(i, i-1, 0, i==len, 1,k);
    return ret;
}


int main()
{
    int i, cas,t1,t2;
    scanf("%d",&cas);
    memset(dp, -1, sizeof(dp));
    for(int ca = 1; ca <= cas; ca++)
    {
        scanf("%lld%lld%d%d",&l,&r,&t1,&t2);//求t1-t2进制有多少个回文串
        if(l > r) swap(l, r);
        LL res=0;
        for (int t=t1;t<=t2;t++)
         res+=(gao(r,t) - gao(l-1,t)) * (t-1) + r - l + 1;
        printf("Case #%d: %lld\n", ca,res);
    }
    return 0;
}

评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值