• hdu6156


    hdu6156

    题意

    ([2, 36]) 进制下,给定区间内的数是回文数的个数。每存在一个回文数,答案加上该回文数的进制。

    分析

    10进制下回文数是 数位DP 很常见的问题,这道题只需要把在转化数字的时候转化成对应的进制即可。
    多开一维数组表示某个进制下的方案数,(dp) 数组只需要一次初始化。

    code

    #include<bits/stdc++.h>
    using namespace std;
    typedef long long ll;
    ll dp[40][60][60]; // 进制,起始位置,长度 (起始位置就是不为 0 的第一个数字)
    int digit[60];
    int num[60];
    ll dfs(int jz, int st, int len, int limit) {
        if(!len) return 1;
        if(!limit && dp[jz][st][len] != -1)
            return dp[jz][st][len];
        ll res = 0;
        int mx = limit ? digit[len] : (jz - 1);
        for(int i = 0; i <= mx; i++) {
            if(st == len && i == 0)
                res += dfs(jz, st - 1, len - 1, limit && i == mx);
            else {
                num[len] = i;
                if((st & 1) == 1) {
                    int mid = ((st + 1) >> 1);
                    if(len >= mid) {
                        res += dfs(jz, st, len - 1, limit && i == mx);
                    } else if(len < mid) {
                        if(num[mid * 2 - len] == i) {
                            res += dfs(jz, st, len - 1, limit && i == mx);
                        }
                    }
                } else {
                    int mid = (st >> 1) + 1;
                    if(len >= mid) {
                        res += dfs(jz, st, len - 1, limit && i == mx);
                    } else {
                        if(num[st + 1 - len] == i) {
                            res += dfs(jz, st, len - 1, limit && i == mx);
                        }
                    }
                }
            }
        }
        if(!limit) dp[jz][st][len] = res;
        return res;
    }
    ll f(int jz, int n) { // jz进制下小于等于 n 的回文数字的个数
        int len = 0;
        while(n) {
            digit[++len] = n % jz;
            n /= jz;
        }
        ll res = dfs(jz, len, len, 1);
        return res;
    }
    int main() {
        memset(dp, -1, sizeof dp);
        int T;
        scanf("%d", &T);
        int Case = 0;
        while(T--) {
            int jz1, jz2;
            int n, m;
            scanf("%d%d%d%d", &n, &m, &jz1, &jz2);
            ll ans = 0;
            for(int i = jz1; i <= jz2; i++) {
                ll num = f(i, m) - f(i, n - 1);
                ans = ans + (1LL * num * i + (m - n + 1 - num));
            }
            printf("Case #%d: %lld
    ", ++Case, ans);
        }
        return 0;
    }
    
  • 相关阅读:
    vue 小知识
    vue中alert toast confirm loading 公用
    vue 跳外链
    vue 中使用 Toast弹框
    vue 添加vux
    #034Python选修课第二届Turtle绘图大赛
    #033 信安培训基础题Python解决网络安全实验室|网络信息安全攻防学习平台
    #031 测试插入博客园插入视频
    # 030删除数组中的重复元素
    #029 博客换个主题从新开始
  • 原文地址:https://www.cnblogs.com/ftae/p/7398287.html
Copyright © 2020-2023  润新知