第一道数位DP的题 不算特别难 转移也好想 就是最后统计答案的时候注意 从高位往低位枚举的时候 一旦有不合法的值出现立即退出 后面统计的都会不合法
#include<cstdio>
#include<algorithm>
#include<cstring>
using namespace std;
const int MAXN = 10;
int d[MAXN+10][MAXN+10], Cur[MAXN+10], Len;
char s1[10], s2[10];
int x;
int main()
{
d[0][0] = 1;
for(int i = 1; i <= MAXN; i++)
for(int j = 0; j <= 9; j++)
if(j != 4)
for(int k = 0; k <= 9; k++)
if(!(j == 6 && k == 2))
d[i][j] += d[i-1][k];
while(scanf("%s%d", s2, &x))
{
x++;
memset(Cur, 0, sizeof(Cur));
sprintf(s1, "%d", x);
Len = strlen(s1);
if(x == 1) break;
for(int i = 0; i < Len; i++) Cur[Len-i] = s1[i] - '0';
int ans = 0;
for(int i = Len; i >= 1; i--)
{
for(int j = 0; j < Cur[i]; j++)
if(!(j == 4 || (Cur[i+1] == 6 && j == 2)))
ans += d[i][j];
if(Cur[i] == 4 || (Cur[i] == 2 && Cur[i+1] == 6)) break;
}
Len = strlen(s2);
memset(Cur, 0, sizeof(Cur));
for(int i = 0; i < Len; i++) Cur[Len-i] = s2[i] - '0';
for(int i = Len; i >= 1; i--)
{
for(int j = 0; j < Cur[i]; j++)
if(!(j == 4 || (Cur[i+1] == 6 && j == 2)))
ans -= d[i][j];
if(Cur[i] == 4 || (Cur[i] == 2 && Cur[i+1] == 6)) break;
}
printf("%d\n", ans);
}
}