[洛谷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;
}

  

猜你喜欢

转载自www.cnblogs.com/Memory-of-winter/p/9832631.html