ICode9

精准搜索请尝试: 精确搜索
首页 > 其他分享> 文章详细

题解 P6754 【[BalticOI 2013 Day1] Palindrome-Free Numbers】

2020-10-28 19:31:53  阅读:195  来源: 互联网

标签:tmp Palindrome int 题解 l1 Free last1 last2 l2


分析:

这道题看着像是\(\;\text{manacher}\)(马拉车),但其实是数位dp

  • 如果某个数上的某一位与它的上一位相同,则这个数肯定是个回文数
  • 同理,如果某个数上的某一位与它的上上一位相同,则这个数肯定也是个回文数

数位dp时要注意前导0的判断。

时间复杂度大概是 \(O(\log(n)\times10)\) 。

代码:

#include "cstdio"
#define W 20
#define E 11
#define int long long
namespace IAKIOI {
const signed L = 1 << 20 | 1;
char buffer[L], *S, *TT;
#define getchar() ((S == TT && (TT = (S = buffer) + fread(buffer, 1, L, stdin), S == TT)) ? EOF : *S++)
inline void read(auto &x) {
    x = 0;
    bool f = false;
    char s = getchar();
    while (s < '0' || s > '9') {
        if (s == '-')
            f = true;
        s = getchar();
    }
    while (s >= '0' && s <= '9') {
        x = x * 10 + s - '0';
        s = getchar();
    }
    f ? -x : x;
}
inline void write(auto x) {
    if (x < 0) {
        putchar('-');
        x = -x;
    }
    if (x > 9)
        write(x / 10);
    putchar(x % 10 + '0');
}
}  // namespace IAKIOI
using namespace IAKIOI;
int pow[W];
inline void getnxt(int &last1, int &last2, int v) {
    if (last1 == 10)
        last1 = v;
    else
        last2 = last1, last1 = v;
}
inline bool judge(int &last1, int &last2, int v) { return v != last1 && v != last2; }
int dp[E][E][W][2];
bool v[E][E][W][2];
inline int work(int last1, int last2, int n, int tmp) {
    if (!n)
        return 1;
    if (v[last1][last2][n][tmp])
        return dp[last1][last2][n][tmp];
    int l1, l2, vis, tot = 0;
    v[last1][last2][n][tmp] = 1;
    for (int i = 0; i <= 9; ++i) {
        vis = (tmp || i) ? 1 : 0;
        l1 = last1;
        l2 = last2;
        if (vis && !judge(l1, l2, i))
            continue;
        if (vis)
            getnxt(l1, l2, i);
        tot += work(l1, l2, n - 1, vis);
    }
    return dp[last1][last2][n][tmp] = tot;
}
inline int solve(int n) {
    int ans = 0, x, last1 = 10, last2 = 10, l1, l2, tmp;
    bool ok = false;
    for (int i = 18; i >= 0; --i)
        if ((x = n / pow[i] % 10) || ok) {
            for (int j = 0; j < x; ++j) {
                tmp = (ok || j) ? 1 : 0;
                l1 = last1, l2 = last2;
                if (tmp && !judge(l1, l2, j))
                    continue;
                if (tmp)
                    getnxt(l1, l2, j);
                ans += work(l1, l2, i, tmp);
            }
            ok = 1;
            if (!judge(last1, last2, x))
                break;
            getnxt(last1, last2, x);
        }
    return ans;
}
signed main() {
    for (int i = pow[0] = 1; i <= 18; ++i) pow[i] = pow[i - 1] * 10;
    int l, r;
    read(l), read(r);
    write(solve(r + 1) - solve(l));
    return 0;
}

标签:tmp,Palindrome,int,题解,l1,Free,last1,last2,l2
来源: https://www.cnblogs.com/nakiri-ayame-suki/p/13892917.html

本站声明: 1. iCode9 技术分享网(下文简称本站)提供的所有内容,仅供技术学习、探讨和分享;
2. 关于本站的所有留言、评论、转载及引用,纯属内容发起人的个人观点,与本站观点和立场无关;
3. 关于本站的所有言论和文字,纯属内容发起人的个人观点,与本站观点和立场无关;
4. 本站文章均是网友提供,不完全保证技术分享内容的完整性、准确性、时效性、风险性和版权归属;如您发现该文章侵犯了您的权益,可联系我们第一时间进行删除;
5. 本站为非盈利性的个人网站,所有内容不会用来进行牟利,也不会利用任何形式的广告来间接获益,纯粹是为了广大技术爱好者提供技术内容和技术思想的分享性交流网站。

专注分享技术,共同学习,共同进步。侵权联系[81616952@qq.com]

Copyright (C)ICode9.com, All Rights Reserved.

ICode9版权所有