[洛谷P4124][CQOI2016]手机号码
题目大意:给你两个$l,r$,求出$[l,r]$中符合要求的数,要求为至少有$3$个相邻的相同数字,且不可以同时出现$8$和$4$
题解:数位$DP$
卡点:无
C++ Code:
#include <cstdio> #include <algorithm> long long l, r; int num[13], tot; long long f[13][4][2][2][11]; long long calc(int x, int lim, int lead, int had48, int len3, int len2, int lst) { if (had48 == 3) return 0; if (!x) return len3; long long F = f[x][had48][len3][len2][lst]; if (!lim && lead && ~F) return F; F = 0; for (int i = lim ? num[x] : 9, op = 1; i + lead; i--, op = 0) { int __had48 = had48; if (i == 4) __had48 |= 1; if (i == 8) __had48 |= 2; F += calc(x - 1, op && lim, lead || i, __had48, len3 | (len2 && (lst == i)), lst == i, i); } if (!lim && lead) f[x][had48][len3][len2][lst] = F; return F; } long long solve(long long x) { if (x < 10000000000) return 0; tot = 0; while (x) { num[++tot] = x % 10; x /= 10; } return calc(tot, 1, 0, 0, 0, 0, 10); } int main() { scanf("%lld%lld", &l, &r); __builtin_memset(f, -1, sizeof f); printf("%lld\n", solve(r) - solve(l - 1)); return 0; }