题解 P6754 【[BalticOI 2013 Day1] Palindrome-Free Numbers】
作者:互联网
分析:
这道题看着像是\(\;\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