题意:
但是同时也掩盖了一个问题,49+1是50,十位自动+1,于是十位的4就可以被读取,但是若把关键字换为48,就得特判一下了;就像本题.///***
还有一个细节问题,在Bomb和windy数中都注意了的,就是高一位的bit[i] = 0;我一直以为我写了的...其实是没写,总是错.
看来对于细节还是略显草率了啊.
另外:给逼得没招了学会了对拍→ →
找出给定区间中不含有4或62的数的个数.思路:
但是这道题就让我对Bomb有更清楚的认识了:这道题关键字是49,用的时候将数++,虽然是因为这种计算本来就只能计算<N的数,本题和Bomb比较像,但是多了一个条件->也不能有4.于是可以想到
其实不需要两个dp,因为求part2的时候dp[i][0]+dp[i][2]就等于dp4[i].先求出part1:不含4的数的个数;
再求part2:不含4且含有62.
但是同时也掩盖了一个问题,49+1是50,十位自动+1,于是十位的4就可以被读取,但是若把关键字换为48,就得特判一下了;就像本题.///***
还有一个细节问题,在Bomb和windy数中都注意了的,就是高一位的bit[i] = 0;我一直以为我写了的...其实是没写,总是错.
看来对于细节还是略显草率了啊.
另外:给逼得没招了学会了对拍→ →
#include <cstdio>
using namespace std;
const int MAXN = 8;
int dp4[MAXN],dp[MAXN][3];
int len;
int bit[MAXN];
void InitDP()
{
dp4[0] = 1;
for(int i=1;i<MAXN;i++)
dp4[i] = dp4[i-1]*9;
dp[0][0] = dp[0][1] = 0;
dp[0][2] = 1;
for(int i=1;i<MAXN;i++)
{
dp[i][0] = dp[i-1][0]*9 + dp[i-1][1];
dp[i][1] = dp[i-1][2];
dp[i][2] = dp[i-1][2]*9 - dp[i-1][1];
}
//for(int i=0;i<MAXN;i++)
// printf("%d:\t\t%d\t%d\t%d\n",i,dp[i][0],dp[i][1],dp[i][2]);
}
void pre(int x, int &len)
{
int i;
for(i=1; x; i++)
{
bit[i] = x % 10;
x /= 10;
}
bit[i] = 0;
len = i-1;
//for(i=len; i; i--)
// printf("bit[%d] = %d\n",i,bit[i]);
}
int cal(int x)
{
int part1 = 0,part2 = 0;
for(int i=len; i; i--)
{
for(int j=0;j<bit[i];j++)
if(j!=4) part1 += dp4[i-1];
if(bit[i]==4) break;
}
bool flag = 0;
for(int i=len; i; i--)
{
for(int j=0;j<bit[i];j++)
{
if(j!=4)
{
part2 += dp[i-1][0];
if(flag) part2 += dp[i-1][2];
if(!flag && bit[i+1]==6 && j==2) part2 += dp[i-1][2];///***
if(!flag && j==6) part2 += dp[i-1][1];
}
}
if(bit[i]==4) break;
if(bit[i]==2 && bit[i+1]==6) flag = 1;
}
//printf("up to %d\texcluding 4 but with 62: %d\n",x,part2);
return part1-part2;
}
int main()
{
int n,m;
InitDP();
while(scanf("%d %d",&n,&m)==2 && (n+m))
{
int ansn,ansm;
pre(++m,len);
ansm = cal(m);
pre(n,len);
ansn = cal(n);
printf("%d\n",ansm-ansn);
}
}