int dfs(int pos,int limit,int lead,int dig,int sum)
{
int ans=0;
if(pos==0)return sum;
if(!limit&&lead&&dp[pos][sum]!=-1) return dp[pos][sum];
int up=9;
if(limit==1)up=num[pos];
for(int j=0;j<=up;j++)
{
int flag=1;
if(lead==0 && j==0)flag=0;
ans+=dfs(pos-1,limit==1 && (j==up) ,flag,dig,sum+(flag && (j==dig)));
}
if(!limit&&lead) dp[pos][sum]=ans;
return ans;
}
其中
p o s pos pos代表搜索到的位置(从高到低)
l i m i t limit limit表示当前 p o s pos pos可不可以取0~9( l i m i t limit limit==1表示不能从0 ~ 9,只能从0~ n u m [ p o s ] num[pos] num[pos])
l e a d lead lead表示是否有前导0(主要是用来判断0的情况,在某些题目里面可以省略)
d i g dig dig表示当前找的是哪个数
s u m sum sum表示从最高位到 p o s pos pos位符合条件的个数
#include
#define ll long long
using namespace std;
template<typename t>void read(t &x)
{
x=0;ll f=1;char ch=getchar();
while(ch<'0' || ch>'9'){if(ch=='-')f=-1;ch=getchar();}
while(ch>='0' && ch<='9'){x=x*10+ch-'0';ch=getchar();}
x=x*f;
}
ll a,b,l,r;
ll dp[20][20],num[20];
void init()
{
freopen("Lg P2602.in","r",stdin);
}
ll dfs(ll pos,ll limit,ll lead,ll dig,ll sum)
{
ll ans=0;
if(pos==0)return sum;
if(!limit&&lead&&dp[pos][sum]!=-1) return dp[pos][sum];
ll up=9;
if(limit==1)up=num[pos];
for(ll j=0;j<=up;j++)
{
ll flag=1;
if(lead==0 && j==0)flag=0;
ans+=dfs(pos-1,limit==1 && (j==up) ,flag,dig,sum+(flag && (j==dig)));
}
if(!limit&&lead) dp[pos][sum]=ans;
return ans;
}
ll solve(ll x,ll digit)
{
memset(dp,-1,sizeof(dp));
ll len=0;
while(x)
{
num[++len]=x%10;
x=x/10;
}
dfs(len,1,0,digit,0);
}
void readdata()
{
read(l),read(r);
}
void work()
{
for(ll i=0;i<=9;i++)
{
printf("%lld ",solve(r,i)-solve(l-1,i));
}
}
int main()
{
// init();
readdata();
work();
return 0;
}
当然也可以找规律
#include
#define ll long long
using namespace std;
template<typename t>void read(t &x)
{
x=0;ll f=1;char ch=getchar();
while(ch<'0' || ch>'9'){if(ch=='-')f=-1;ch=getchar();}
while(ch>='0' && ch<='9'){x=x*10+ch-'0';ch=getchar();}
x=x*f;
}
ll lef[1005],rit[1005];
ll l,r,x,m;
void init()
{
freopen("Lg P2602.in","r",stdin);
}
void readdata()
{
read(l),read(r);
l=l-1;
}
void work()
{
for(ll t=0;t<=9;t++)
{
x=t;
m=1;
while(m<=l)
{
ll a=l/(m*10),b=l/m%10,c=l%m;
if(x)
{
// 755
if(b>x) lef[t]+=(a+1)*m;
if(b==x)lef[t]+=a*m+c+1;
if(b<x) lef[t]+=a*m;
}
// 0705
else
{
if(b) lef[t]+=a*m;
else lef[t]+=(a-1)*m+c+1;
}
m=m*10;
}
}
for(ll t=0;t<=9;t++)
{
x=t;
m=1;
while(m<=r)
{
ll a=r/(m*10),b=r/m%10,c=r%m;
if(x)
{
// 755
if(b>x) rit[t]+=(a+1)*m;
if(b==x)rit[t]+=a*m+c+1;
if(b<x) rit[t]+=a*m;
}
else
{
if(b) rit[t]+=a*m;
else rit[t]+=(a-1)*m+c+1;
}
m=m*10;
}
}
for(ll i=0;i<=9;i++)
{
printf("%lld ",rit[i]-lef[i]);
}
}
int main()
{
// init();
readdata();
work();
return 0;
}
在DFS内部特判即可
#include
using namespace std;
template<typename t>void read(t &x)
{
x=0;int f=1;char ch=getchar();
while(ch<'0' || ch>'9'){if(ch=='-')f=-1;ch=getchar();}
while(ch>='0' && ch<='9'){x=x*10+ch-'0';ch=getchar();}
x=x*f;
}
int dp[20][20],num[20];
int l,r;
int dfs(int pos,int limit,int lead,int last)
{
int ans=0;
if(pos==0)return 1;
if(limit==0 && lead==1 && dp[pos][last]!=-1)return dp[pos][last];
int up=9;
if(limit)up=num[pos];
for(int j=0;j<=up;j++)
{
if(abs(j-last)<2)continue;
int flag=1,lastt=j;
if(lead==0 && j==0)flag=0;
if(flag==0)lastt=-2333;
ans+=dfs(pos-1,limit && (up==j),flag,lastt);
}
if(limit==0 && lead==1)dp[pos][last]=ans;
return ans;
}
int solve(int x)
{
memset(dp,-1,sizeof(dp));
int tot=0;
while(x)
{
num[++tot]=x%10;
x=x/10;
}
return dfs(tot,1,0,-2333);
}
void init()
{
freopen("Lg P2657.in","r",stdin);
}
void readdata()
{
read(l),read(r);
}
void work()
{
printf("%d",solve(r)-solve(l-1));
}
int main()
{
// init();
readdata();
work();
return 0;
}
#include
using namespace std;
int num[200],dp[200][200];
int l,r;
int dfs(int pos,int limit,int last)
{
int ans=0;
if(pos==0)return 1;
if(limit==0 && dp[pos][last]!=-1)return dp[pos][last];
int up=9;
if(limit)up=num[pos];
for(int i=last;i<=up;i++)
{
ans+=dfs(pos-1,limit && (i==up),i);
}
if(limit==0)dp[pos][last]=ans;
return ans;
}
int solve(int x)
{
memset(dp,-1,sizeof(dp));
int tot=0;
while(x)
{
num[++tot]=x%10;
x=x/10;
}
return dfs(tot,1,0);
}
void init()
{
freopen("Loj 10164.in","r",stdin);
}
void readdata()
{
while(scanf("%d %d",&l,&r)!=EOF)
{
printf("%d\n",solve(r)-solve(l-1));
}
}
int main()
{
//init();
readdata();
return 0;
}
#include
#define ll long long
using namespace std;
ll num[200];
ll dp[200][200];
ll a,b,mod;
ll dfs(ll pos,ll limit,ll judge)
{
ll ans=0;
if(pos==0)
{
if(judge==0)return 1;
else return 0;
}
if(limit==0 && dp[pos][judge]!=-1)return dp[pos][judge];
ll up=9;
if(limit)up=num[pos];
for(ll i=0;i<=up;i++)
{
ans+=dfs(pos-1,limit && (i==up),(judge+i)%mod);
}
if(limit==0)dp[pos][judge]=ans;
return ans;
}
ll solve(ll x)
{
memset(dp,-1,sizeof(dp));
ll tot=0;
while(x)
{
num[++tot]=x%10;
x=x/10;
}
return dfs(tot,1,0);
}
void init()
{
freopen("Loj10166.in","r",stdin);
}
void readdata()
{
while(scanf("%d%d%d",&a,&b,&mod)!=EOF)
{
printf("%lld\n",solve(b)-solve(a-1));
}
}
int main()
{
// init();
readdata();
return 0;
}
#include
#define ll long long
using namespace std;
ll num[20];
ll dp[10][2][10];
ll l,r;
ll dfs(ll pos,ll limit,ll type,ll pre)
{
if(pos==0)return type;
if(!limit && dp[pos][type][pre]!=-1)return dp[pos][type][pre];
ll up=9,ans=0,nexttype=0;
if(limit)up=num[pos];
for(ll i=0;i<=up;i++)
{
nexttype=0;
if(type||i==4||(i==2&&pre==6))nexttype=1;
ans+=dfs(pos-1,limit && (up==i),nexttype,i);
}
if(limit==0)dp[pos][type][pre]=ans;
return ans;
}
ll solve(ll x)
{
memset(dp,-1,sizeof(dp));
ll tot=0;
while(x)
{
num[++tot]=x%10;
x=x/10;
}
return dfs(tot,1,0,0);
}
void init()
{
freopen("Loj10167.in","r",stdin);
}
void readdata()
{
while(scanf("%d%d",&l,&r)!=EOF)
{
if(l==0 && r==0)break;
printf("%d\n",r-l+1-(solve(r)-solve(l-1)));
}
}
int main()
{
// init();
readdata();
return 0;
}