题意:给定一个区间,求这个区间内不含4和62(6,2连续)的数的个数。
分析:数位dp,此题可由低位递推高位,dp[i][0]表示i位数无不吉利数字,dp[i][1]表示i位数无不吉利数字且最高位为2,dp[i][2]表示i位数有不吉利数字。
#include<iostream>
#include<string>
#include<cstring>
#include<cstdio>
#include<cmath>
#include<iomanip>
#include<map>
#include<algorithm>
#include<queue>
#include<set>
#define inf 10000000
#define pi acos(-1.0)
#define eps 1e-8
#define seed 131
using namespace std;
typedef pair<int,int> pii;
typedef unsigned long long ULL;
typedef long long LL;
const int maxn=100005;
int n,m;
int dp[10][3];
int solve(int x);
//dp[i][0]:i位无不吉利
//dp[i][1]:i位无不吉利,最高位为2
//dp[i][2]:i位有不吉利
int main()
{
memset(dp,0,sizeof(dp));
dp[0][0]=1;
for(int i=1;i<=8;i++)
{
dp[i][0]=dp[i-1][0]*9-dp[i-1][1];//在首位加除4外的9个数,减去i-1位最高位为2且在首位加6
dp[i][1]=dp[i-1][0];
dp[i][2]=dp[i-1][2]*10+dp[i-1][0]+dp[i-1][1];
}
while(~scanf("%d%d",&n,&m))
{
if(n==0&&m==0)
break;
printf("%d\n",solve(m+1)-solve(n));
}
return 0;
}
int solve(int x)//求得0-(x-1)满足条件的数的个数
{
int xx=x-1;
int digit[10];
int cnt;
for(cnt=1;;cnt++)
{
digit[cnt]=x%10;
x/=10;
if(x==0)
break;
}
digit[cnt+1]=0;
int ans=0;
bool flag=false;
for(int i=cnt;i>0;i--)//从高位到低位依次比较
{
ans+=digit[i]*dp[i-1][2];
if(flag)
ans+=digit[i]*dp[i-1][0];
else
{
if(digit[i]>6)
ans+=dp[i-1][1];
if(digit[i]>4)
ans+=dp[i-1][0];
if(digit[i+1]==6&&digit[i]>2)
ans+=dp[i][1];
}
if(digit[i]==4||(digit[i+1]==6&&digit[i]==2))
flag=true;
}
return xx-ans;
}