CF Educational Codeforces Round 50 C. Classy Numbers
? 解题记录 ? ? Codeforces ? ? 动态规划 ? ? 数位dp ? ? 搜索 ?    2018-09-13 22:52:19    482    0    0
output
standard output

Let's call some positive integer classy if its decimal representation contains no more than 33 non-zero digits. For example, numbers 442000002000001020310203 are classy and numbers 4231423110230610230672774200007277420000 are not.

You are given a segment [L;R][L;R]. Count the number of classy integers xx such that LxRL≤x≤R.

Each testcase contains several segments, for each of them you are required to solve the problem separately.

Input

The first line contains a single integer TT (1T1041≤T≤104) — the number of segments in a testcase.

Each of the next TT lines contains two integers LiLi and RiRi (1LiRi10181≤Li≤Ri≤1018).

Output

Print TT lines — the ii-th line should contain the number of classy integers on a segment [Li;Ri][Li;Ri].

Example
input
Copy
41 10001024 102465536 65536999999 1000001
output
Copy
1000102​​

 

题目大意:找出N以内的不超过3个位置为0的数的个数。

考虑数位dp,但是考场上的写法太复杂了,其实只需要用不加任何限制的减去前面高位都是和N一样的方案数就可以了。

但是其实还是复杂了,这道题可以直接dfs出所有合法的数,然后二分答案,考虑这样的数大概不会超过1e6个。

#include<cstdio>
#include<algorithm>
#include<cstring>
#define LL long long
using namespace std;

LL dp[25][4][2], x, l, r;
int dig[25], cnt, q;

void indig(LL n) {
	while(n) {
		dig[++cnt] = n % 10;
		n /= 10;
	}
}

LL GetAns(LL n) {
	memset(dp, 0, sizeof(dp));
	if(n == 0) return 1;
	cnt = 0, indig(n);
	dp[cnt + 1][0][1] = 1;
	for(register int i = cnt + 1; i > 1; --i) {
		for(register int j = 0; j <= 2; ++j) {
				dp[i - 1][j][0] += dp[i][j][0];
				dp[i - 1][j + 1][0] += dp[i][j][0] * 9;
				if(dig[i - 1] > 1)
					dp[i - 1][j + 1][0] += dp[i][j][1] * (dig[i - 1] - 1);
				if(dig[i - 1] > 0) {
					dp[i - 1][j + 1][1] += dp[i][j][1];
					dp[i - 1][j][0] += dp[i][j][1];
				}
				else dp[i - 1][j][1] += dp[i][j][1];				
		}
		if(dig[i - 1] > 1) {
			dp[i - 1][3][0] += dp[i][3][1];
		} else dp[i - 1][3][1] += dp[i][3][1];
		dp[i - 1][3][0] += dp[i][3][0];
	}
	LL ans = 0;
	for(register int i = 0; i <= 1; ++i)
		ans += dp[1][0][i] + dp[1][1][i] + dp[1][2][i] + dp[1][3][i];
	return ans;
}

int main() {
	scanf("%d", &q);
	while(q--) {
		scanf("%I64d%I64d", &l, &r);
		//printf("%I64d\n%I64d\n", GetAns(r), GetAns(l - 1));
		printf("%I64d\n", GetAns(r) - GetAns(l - 1));
	}
	return 0;
}


上一篇: CF#483 Div2 D. XOR-pyramid

下一篇: BZOJ3534: [Sdoi2014]重建

482 人读过
立即登录, 发表评论.
没有帐号? 立即注册
0 条评论
文档导航