思路:
了解过数位的,这题一定是可以写出来的.
我们用表示到了第i位无限制的条件下填了
个
~
的方案数.然后对于限制和非限制进行一个讨论即可.就是一个简单的递归,最后答案是
.
但是有个细节值得注意,了我一会,就是你
应该放到返回答案的前面,不然就会出
..数组越界.(因为我只开了
.)
代码:
#include <bits/stdc++.h>
using namespace std;
typedef long long ll;
const int N=21,M=4;
ll f[N][M];//到了第i位无限制的条件下填了j个1~9的方案数.
int a[N];
ll dfs(int len,int num,int limit)
{
if(num>3) return 0;
if(!limit&&f[len][num]!=-1) return f[len][num];
if(len==0) return 1;
ll res=0;
if(limit)
{
for(int i=0;i<=a[len];i++)
{
if(i<a[len]) res+=dfs(len-1,num+(i!=0),!limit);
else res+=dfs(len-1,num+(i!=0),limit);
}
}
else
{
res+=dfs(len-1,num,limit);
res+=9ll*dfs(len-1,num+1,limit);
}
if(!limit) return f[len][num]=res;
else return res;
}
ll solve(ll x)
{
int id=0;
if(x==0) return 1ll;
while(x) a[++id]=x%10,x/=10;
return dfs(id,0,1);
}
int main()
{
int T;cin>>T;
memset(f,-1,sizeof f);
while(T--)
{
ll l,r;cin>>l>>r;
printf("%lld\n",solve(r)-solve(l-1));
}
return 0;
}
京公网安备 11010502036488号