题目意思:输入两个数代表l(左区间),r(右区间)。然后找出在这个区间内不含62和4这两个数字的数,计算它们的个数。

这是一个数位dp的入门题,所以只要了数位dp就会了。

数位dp其实就是暴力枚举,直白点说就是从一个数的最高位一直到最低位(个位)找数然后比较看符不符合条件。

对于这个题目就是找没有62和4的数,但是6x2也是可以的,我们需要把一个数拆分成一个个的数字去判断,下面就看代码吧。

 1 #include<iostream>
 2 #include<string.h>
 3 using namespace std;
 4 #define ll long long
 5 ll disit[20];                       //这个数组是用来储存拆分后的数的
 6 ll dp[20][2];                       //如果只需要判断一位数字的话dp[20]就可以,但是这里除了判断是否有4之外还要判断有没有62(这是一个两位数)所以是dp[20][2]
 7 ll dfs(int len,bool sta_6,bool limit)
 8 {
 9     if(!len) return 1;
10     if(!limit&&dp[len][sta_6]!=-1) return dp[len][sta_6];
11     ll ans=0, Maxn=(limit?disit[len]:9);
12     for(int i=0;i<=Maxn;i++)
13     {
14         if(i==4)                    //根据题目要求跳过不符合条件的数
15             continue ;
16         if(i==2&&sta_6)
17             continue ;
18         ans+=dfs(len-1,i==6,limit&&i==Maxn);
19     }
20     if(!limit)
21         dp[len][sta_6]=ans;                //记忆化
22     return ans;
23 }
24 //拆数
25 ll solve(ll x)
26 {
27     memset(disit,0,sizeof(disit));
28     int len=0;
29     while(x)
30     {
31         disit[++len]=x%10;
32         x/=10;
33     }
34     return dfs(len,false,true);
35 }
36 int main()
37 {
38     int l,r;
39     memset(dp,-1,sizeof(dp));
40     while(cin>>l>>r&&l+r)
41     {
42         cout<<solve(r)-solve(l-1)<<endl;
43     }
44     return 0;
45 }
View Code