思路:
模板题,详细思路看代码注释。
AC code:
#include<iostream>
#include<cstdio>
#include<cstring>
using namespace std;
const int maxn = 10;
int dp[maxn][maxn];//dp[i][0]表示i位数中,幸运数的个数,dp[i][1]:以2开头的幸运数的个数
//dp[i][2]:非幸运数的个数
void init(){ //计算DP
memset(dp,0,sizeof(dp));
dp[0][0] = 1;//初始值确定,靠代入法
for(int i = 1;i <= 7;++i){
dp[i][0] = dp[i-1][0] * 9 - dp[i-1][1];
dp[i][1] = dp[i-1][0];
dp[i][2] = dp[i-1][0] + dp[i-1][1] + dp[i-1][2] * 10;
}
}
int solve(int x){
int temp = x;
int digit[10];
memset(digit,0,sizeof(digit));
int k = 0;
while(temp > 0){//取出数位
digit[++k] = temp % 10;
temp /= 10;
}
int ans = 0,flag = 0;
digit[k+1] = 0;
for(int i = k;i >= 1;--i){
//cout << "en " << dp[i-1][2] << endl;
ans += digit[i] * dp[i-1][2];//除去本身 ,加上非幸运数
if(flag == 1){
ans += digit[i] * dp[i-1][0];//前面的位有4 or 62 所以后面的数任意
}else{
if(digit[i] > 4){//不能等于4,因为0-39999,若==4,就不会列举完,比如45555
ans += dp[i-1][0];
}
if(digit[i] > 6){//不能等于6,62后面的数要任意,所以>6
ans += dp[i-1][1];
}
if(digit[i+1] == 6 && digit[i] > 2){//别遗忘这种情况,只要>63,后面的就可以
ans += dp[i][1];//注意是i,不是i-1
}
}
if(digit[i] == 4 || (digit[i+1] == 6 && digit[i] == 2)){
flag = 1;
}
}
//cout << ans << endl;
return x - ans;
}
int main(){
int n = 0,m = 0;
init(); //不要忘记初始化了
while(cin >> n >> m && (m >= n) && n){
cout << solve(m+1) - solve(n) << endl;
}
return 0;
}