ll f(ll x)
{
if(x==1e10) return 0; //为什么这里加上这句话才能过1 4 5 这3个点.但是加上这个判断这组数据1e10 1e10,这个数据就错了啊,我输出负的
mem(dp,-1);
ll pos = 0;
while(x)
{
va[++pos] = x%10;
x /= 10;
}
return dfs(pos,-1,-1,0,0,0,1,1);
}
下面是整体源代码:
#include<iostream>
#include<cstring>
#include<string>
#include<math.h>
#include<algorithm>
#include<vector>
#include<queue>
#include<stack>
#include<map>
#include<set>
//#pragma GCC optimize(2)
#define eps 1e-9
#define fi first
#define se second
#define pb push_back
#define db double
#define ll long long
#define PII pair<int,int >
#define cin(x) scanf("%d",&x)
#define cout(x) printf("%d ",x)
#define fuck(x) cout<<"#: "<<x<<endl
#define mem(a,b) memset(a,b,sizeof(a))
#define IOS std::ios::sync_with_stdio(false),cin.tie(0),cout.tie(0);
using namespace std;
const int N = 5e5,M = 200;
const int inf = 0x3f3f3f3f;
const double pai = acos(-1);
ll l,r;
ll sum;
ll va[M];
ll dp[20][20][20][2][2][2];
ll f(ll x);
ll dfs(ll pos,ll pre1,ll pre2,ll is3,ll is4,ll is8,ll limit,ll lead);
int main()
{
cin>>l>>r;
cout<<f(r)-f(l-1);
return 0;
}
ll dfs(ll pos,ll pre1,ll pre2,ll is3,ll is4,ll is8,ll limit,ll lead)
{
if(is4&&is8) return 0;
if(not pos) return is3;
if(!limit&&!lead&&pre1!=-1&&pre2!=-1&&dp[pos][pre1][pre2][is3][is4][is8]!=-1)
return dp[pos][pre1][pre2][is3][is4][is8];
int up = limit?va[pos]:9;
ll res = 0;
for(int i=0;i<=up;i++)
{
int lead_t = lead&&i==0;
int is3_t = is3||(i==pre1&&i==pre2);
int t1 = lead_t?-1:i;
int t2 = lead_t?-1:pre1;
res += dfs(pos-1,t1,t2,is3_t,is4||(i==4),is8||(i==8),limit&&i==up,lead&&i==0);
}
if(!limit&&!lead&&pre1!=-1&&pre2!=-1)
dp[pos][pre1][pre2][is3][is4][is8] = res;
return res;
}
ll f(ll x)
{
if(x==1e10) return 0;
mem(dp,-1);
ll pos = 0;
while(x)
{
va[++pos] = x%10;
x /= 10;
}
return dfs(pos,-1,-1,0,0,0,1,1);
}