题目大意:求出给定区间内,不包含62 和 4 的数字的个数
思路在代码里面,细节蛮多的,注意一下
#include<iostream>
#include<cstring>
#include<cstdio>
#include<algorithm>
using namespace std;
const int MAXN = 10;
int dp[MAXN][2];
//dp[i][0] 表示长度为i的任意数字中不含4 也不含62 的数字的个数
//dp[i][1] 表示长度为i的任意数字中不含 4 也不含62, 但是以2开头的数字的个数
int a,b;
void init()
{
dp[0][0]=1;
for(int i=1;i<MAXN;i++)
{
dp[i][0] = dp[i-1][0]*9-dp[i-1][1];
dp[i][1] = dp[i-1][0];
}
}
int num[MAXN],len;
#define fuck printf("fuck\n");
int solve(int n)
{
len=1;
int temp = n;
while(n)
{
num[len++]=n%10;
n/=10;
}
num[len]=0;len--;
int ans =0 ;
for(int i=len;i;i--)
{
//不能使用数字4
if(num[i]>4)ans +=dp[i-1][0]*(num[i]-1);
else ans += dp[i-1][0]*num[i];
//如果当前位大于6,那么6可以和后一位的2开头的不包含62的数字组成一个62,所以要减去
if(num[i]>6)ans -= dp[i-1][1];
//如果符合下面条件,同上,注意减去的数字长度
if(num[i+1]==6&&num[i]>2) {ans -= dp[i][1];}
//printf("nun--%d ans--%d\n",num[i],ans);
//如果数字本身出现了62或者4,那么就可以直接跳出了
if(num[i+1]==6&&num[i]==2)break;
if(num[i]==4)break;
}
//printf("num=%d ans=%d\n",temp,ans);
return ans ;
}
#define bug3
void debug()
{
for(int i=0;i<=3;i++)
{
for(int j=0;j<2;j++)
{
printf("dp[%d][%d]->%d\n",i,j,dp[i][j]);
}
}
}
int main()
{
freopen("data.in","r",stdin);
freopen("me.out","w",stdout);
init();
#ifdef bug
debug();
#endif
while(scanf("%d%d",&a,&b)&&(a+b))
{
//printf("%d %d \n",a,b);
printf("%d\n",solve(b+1)-solve(a));
}
return 0;
}