/*
参考http://www.cnblogs.com/kuangbin/archive/2013/04/30/3052424.html
数位dp;
也可以暴力打表;
*/
#include<iostream>
#include<string.h>
using namespace std;
int dp[10][3];
/*
dp[i][0] 代表不存在不吉利的数字;
dp[i][1] 代表不存在不吉利的数字,但是首位为2;
dp[i][2] 代表存在不吉利的数字个数
*/
void run1()
{
int i;
dp[0][0] = 1;
dp[0][1] = dp[0][2] = 0;
for( i=1; i <= 6; i++ )
{
dp[i][0] = dp[i-1][0]*9 - dp[i-1][1];//首位除了4以为的减去前一位不吉利数的个数
dp[i][1] = dp[i-1][0];//首位为2的情况
dp[i][2] = dp[i-1][2]*10 + dp[i-1][0] + dp[i-1][1];
//前一项不不吉利的,首位是任何数都是不吉利的,再加上首位62,和4的;
}
}
int run(int n)
{
int s=0, i, l = 0, a[10];
int temp = n;
a[0] = 0;
while(n)
{
a[++l] = n % 10;
n /= 10;
}
a[l+1] = 0;//注意清空
bool p = false;
for( i=l; i > 0; i-- )
{
s += dp[i-1][2] * a[i];//由上位所有不吉利的数推导
if(p)
s += dp[i-1][0] * a[i];//a[i+1]已经存在不吉利的数了,后面的数任意
else
{
if(a[i] > 4)
s += dp[i-1][0];
if(a[i] > 6 )
s += dp[i-1][1];
if(a[i+1] == 6 && a[i] > 2)
s += dp[i][1];
}
if(a[i] == 4 || (a[i+1] == 6 && a[i] == 2))
p = true;
}
if(p) s++;//这个数本身
return temp-s;//所有的数减去不吉利的数;
}
int main()
{
int n, m;
run1();
while(scanf("%d%d", &n, &m) != EOF && (n || m))
printf("%d\n", run(m) - run(n-1));
return 0;
}
/*
152 125244
71720
*/
暴力打表代码
#include<iostream>
#include<string>
#define Max 1000002
using namespace std;
int f[Max];
char ch[Max];
void set()
{
for(int i=1; i < Max; i++ )
{
itoa(i, ch, 10);
if(strstr(ch, "62") || strstr(ch, "4"))
f[i] = 1;
}
}
int main()
{
set();
int n, m;
while(scanf("%d%d", &n, &m) != EOF && n || m )
{
int i, sum = 0;
for( i=n; i <= m; i++ )
{
if(f[i] == 1)
sum++;
}
printf("%d\n", m-n - sum + 1);
}
return 0;
}