#include <map>
#include <set>
#include <stack>
#include <queue>
#include <cmath>
#include <ctime>
#include <vector>
#include <cstdio>
#include <cctype>
#include <cstring>
#include <cstdlib>
#include <iostream>
#include <algorithm>
using namespace std;
#define INF 0x3f3f3f3f
#define inf -0x3f3f3f3f
#define lson l,m,rt<<1
#define rson m+1,r,rt<<1|1
#define mem0(a) memset(a,0,sizeof(a))
#define mem1(a) memset(a,-1,sizeof(a))
#define mem(a, b) memset(a, b, sizeof(a))
typedef long long ll;
int dp[10][3];
//dp[i][0] 位数为i且不含不吉利数字
//dp[i][1] 位数为i且不含不吉利数字且第一位为2
//dp[i][2] 位数为i且含不吉利数字
void init(){
mem0(dp); //dp数组置0
dp[0][0]=1;
for(int i=1;i<=6;i++){ //最多有6位
dp[i][0]=dp[i-1][0]*9-dp[i-1][1]; //前i-1为不含不吉利数字且排除4的情况-第i位为6且i-1位为2的情况
dp[i][1]=dp[i-1][0];
dp[i][2]=dp[i-1][2]*10+dp[i-1][0]+dp[i-1][1]; //dp[i-1][0]表示第一位为4,dp[i-1][1]第一位为6
// cout<<dp[i][0]<<"PPPPP"<<dp[i][1]<<"PPPPP"<<dp[i][2]<<endl;
}
}
int solve(int n){
int a[10];
int len=0;
int tmp=n;
while(n){
a[++len]=n%10;
n/=10;
}
int ans=0,flag=0;
a[len+1]=0;
for(int i=len;i>=1;i--){
ans+=dp[i-1][2]*a[i]; //则下面的情况dp[i-1]都是吉利数字
if(flag){
ans+=dp[i-1][0]*a[i]; //如果存在不吉利树,任意处理
}
if(!flag&&a[i]>4){ //首位大于4,则出去首位可以放一的情况
ans+=dp[i-1][0];
}
if(!flag&&a[i+1]==6&&a[i]>2) //前一位为6,则除去这一位第一个数放2的情况
ans+=dp[i][1];
if(!flag&&a[i]>6) //除去下一位第一个数放1的情况
ans+=dp[i-1][1];
if(a[i]==4||(a[i+1]==6&&a[i]==2))
flag=1;
// cout<<i<<"PPPPP"<<ans<<endl;
}
return tmp-ans;
}
int main(){
int n,m;
init();
while(scanf("%d%d",&n,&m)==2){
if(n==0&&m==0)
break;
printf("%d\n",solve(m+1)-solve(n)); //如果直接为solve(m)的话未把m是否为不吉利数字考虑进去
}
return 0;
}
HDU2089 不要62(数位dp)
最新推荐文章于 2021-07-24 21:31:32 发布