统计区间 [a,b] 中不含 4 和 62 的数字有多少个。
#include<iostream>
#include<cstdio>
#include<cstring>
using namespace std;
int f[8][2],bit[8];
/*
f[i][j]:i是位数
j==0,尾位不是6
j==1,尾位是6
*/
int dfs(int pos,bool six,bool limit)
{
if(pos<=0)return 1;
if(!limit&&f[pos][six]!=-1)return f[pos][six];
int up=limit?bit[pos]:9;
int ans=0;
for(int i=0;i<=up;i++)
{
if(six&&i==2)continue;
if(i==4)continue;
ans+=dfs(pos-1,i==6,limit&&i==up);
}
if(!limit)f[pos][six]=ans;
return ans;
}
int solve(int x)
{
memset(bit,-1,sizeof(bit));
int len=0;
while(x)
{
bit[++len]=x%10;
x/=10;
}
dfs(len,0,1);
}
int main()
{
int a,b;
while(~scanf("%d%d",&a,&b)&&(a+b)){
printf("%d\n",solve(b)-solve(a-1));
}
return 0;
}
#include<iostream>
#include<cstdio>
#include<cstdlib>
#include<cmath>
#include<cstring>
#include<algorithm>
#prag\
ma GCC optimize("O3")
using namespace std;
typedef long long LL;
typedef unsigned long long uLL;
#define REP(i, a, b) for(register int i = (a), i##_end_ = (b); i <= i##_end_; ++ i)
#define DREP(i, a, b) for(register int i = (a), i##_end_ = (b); i >= i##_end_; -- i)
#define mem(a, b) memset((a), b, sizeof(a))
template<typename T> inline bool chkmin(T &a, const T &b) { return a > b ? a = b, 1 : 0; }
template<typename T> inline bool chkmax(T &a, const T &b) { return a < b ? a = b, 1 : 0; }
int read()
{
register int sum = 0,fg = 0;char c = getchar();
while(c < '0' || c > '9') { fg |= c == '-'; c = getchar(); }
while(c >= '0' && c <= '9') { sum = sum * 10 + c - '0'; c = getchar(); }
return fg ? -sum : sum;
}
const int inf = 1e9;
const int maxn = 100000;
int n,m,num;
int a[maxn];
void fj(int x)
{
num = 0;
while(x){a[num++] = x % 10;x/=10;}//分解每个位上数字;
}
int dp[1010][2];//dp[i][j]表示dp到i位前一位是不是6?的方案数
int dfs(int pos,int pre,int flag,bool lim)//数位dp精华
{
if(pos == -1)return 1;//搜到叶子节点返回
if(!lim && dp[pos][flag] != -1)return dp[pos][flag];//要没有上限才能返回,因为可能引起状重复
int up = lim ? a[pos] : 9;//上限 ,每个数对应的上限
int sum = 0;
REP(i,0,up)
{
if(pre == 6 && i == 2)continue;
if(i == 4)continue;//搜索可行状态 //两者都不行
sum += dfs(pos-1,i,i==6,lim && i == a[pos]); //继续深搜,最后一个语句判断是否有限制;
}
if(!lim)dp[pos][flag] = sum;//没限制,
return sum;//return;
}
int main()
{
while(scanf("%d%d",&n,&m) && n + m)
{
mem(dp,-1);fj(m);
int ans = dfs(num-1,-1,0,1);
fj(n-1);
ans -= dfs(num-1,-1,0,1);//前缀和思想 //所减区间就是所求;
cout<<ans<<endl;
}
return 0;
}