自己的主体思路,没有什么问题,有一个情况没有考虑清楚,但主要还是边界出了问题
失误的情况是:4和8,不能同时出现,但不代表不能出现两个4,这里当时就记了一个参数,当时以为自己想到了一个巧妙的方法(原来是个巧妙的错误。。)
经验——避免这种没有情况的方法就是,1:考场上要对拍 2:注意尝试以一种,怀疑的态度审视自己的思路,再三思考自己认为正确的思路
3:有一个,好的方向就是:尽管wa了好多次,也不放弃自己独特的方法,既然我认为他没有错误,就坚持下去,毕竟创新思维最为重要!!
4:边界!边界!出数据的时候要特别注意边界!!包括各种!!这里是最大边界和最小边界!
就是数位dp的基本做法。
#include<cstdio>
#include<cstring>
#include<cstdlib>
#include<cmath>
#include<algorithm>
using namespace std;
typedef long long ll;
ll f[20][2][12][2][2][2];
int li[20];
ll dfs(int i,bool same,int last,bool apr,bool a8,bool a4,bool limit)
{
if (i==0&&apr) return 1;
if (i==0) return 0;
if (!limit)
if (f[i][same][last][apr][a8][a4]!=-1)
return f[i][same][last][apr][a8][a4];
int up=limit? li[i]:9;
ll ans=0;
for (int j=0;j<=up;j++)
{
if (j==4&&a8) continue;
if (j==8&&a4) continue;
ans+=dfs(i-1,last==j,j,apr||(same&&last==j),j==8||a8,j==4||a4,limit&&j==up);
}
if (!limit) f[i][same][last][apr][a8][a4]=ans;
return ans;
}
ll work(ll n)
{
memset(f,-1,sizeof(f));
memset(li,0,sizeof(li));
int tot=0;
while (n)
{
li[++tot]=n%10;
n=n/10;
}
return dfs(tot,false,0,false,false,false,true);
}
int main()
{
ll l,r;
scanf("%lld%lld",&l,&r);
ll ans=work(r);
if (l==10000000000ll) l++,ans++;
ans=ans-work(l-1);
printf("%lld",ans);
return 0;
}