BZOJ4521&&洛谷P4124 [CQOI2016]手机号码

搜索大法好

代码比较清楚就不细讲了,为了避免前导零,我们直接枚举第一位就行了

代码

//By AcerMo
#include<cmath>
#include<cstdio>
#include<cstring>
#include<iostream>
#include<algorithm>
#define lli long long int
using namespace std;
lli num[12];
lli f[11][11][11][2][2][2][2];
inline lli dfs(int p,int l1,int l2,bool can,bool jud,bool l4,bool l8)
{
	//l1倒数第二位,l2倒数第一位,can之前有没有连续的三个相同数字,l4->4出没出现过,l8同理 
    if(l4&&l8) return 0;
    if(p<=0) return can;
    if (f[p][l1][l2][can][jud][l4][l8]!=-1) return f[p][l1][l2][can][jud][l4][l8];
    lli emm=!jud?num[p]:9,ans=0;
    for(int i=0;i<=emm;i++)
    ans+=dfs(p-1,i,l1,can||(i==l2&&i==l1),jud||(i<emm),l4||(i==4),l8||(i==8));
    return f[p][l1][l2][can][jud][l4][l8]=ans;
}
inline void slove(lli x,lli y)
{
	lli len=0,ans=0;
	memset(f,-1,sizeof(f));
	while(x) num[++len]=x%10,x/=10;
    for(int i=1;i<=num[len];i++)
    ans+=dfs(len-1,i,0,0,i<num[len],i==4,i==8);
    if (len<11) ans=0;
    lli lon=0,que=0;
	memset(f,-1,sizeof(f));
    while(y) num[++lon]=y%10,y/=10;
    for(int i=1;i<=num[lon];i++)
    que+=dfs(lon-1,i,0,0,i<num[lon],i==4,i==8);
    if (lon<11) que=0;
	cout<<que-ans;
	return ; 
}
signed main()
{
    lli l,r;cin>>l>>r;slove(l-1,r);
    return 0;
}

 

评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值