题目
题意翻译
定义一个数字是“好数”,当且仅当它的十进制表示下有不超过33个数字1 \sim 91∼9
举个例子:4,200000,102034,200000,10203是“好数”,然而4231,102306,72774200004231,102306,7277420000不是
给定[l,r][l,r],问有多少个xx使得l \le x \le rl≤x≤r,且xx是“好数”
一共有T(1 \le T \le 10^{4})T(1≤T≤10
4
)组数据,对于每次的询问,输出一行一个整数表示答案
1 \le l_i \le r_i \le 10^{18}1≤l
i
≤r
i
≤10
18
题目描述
Let’s call some positive integer classy if its decimal representation contains no more than 3 3 non-zero digits. For example, numbers 4 4 , 200000 200000 , 10203 10203 are classy and numbers 4231 4231 , 102306 102306 , 7277420000 7277420000 are not.
You are given a segment [L; R] [L;R] . Count the number of classy integers x x such that L \le x \le R L≤x≤R .
Each testcase contains several segments, for each of them you are required to solve the problem separately.
输入输出格式
输入格式:
The first line contains a single integer T T ( 1 \le T \le 10^4 1≤T≤10
4
) — the number of segments in a testcase.
Each of the next T T lines contains two integers L_i L
i
and R_i R
i
( 1 \le L_i \le R_i \le 10^{18} 1≤L
i
≤R
i
≤10
18
).
输出格式:
Print T T lines — the i i -th line should contain the number of classy integers on a segment [L_i; R_i] [L
i
;R
i
] .
输入输出样例
输入样例#1: 复制
4
1 1000
1024 1024
65536 65536
999999 1000001
输出样例#1: 复制
1000
1
0
2
思路
一般地,数位dp可以用来解决下面的问题: 给定一个结果为bool类型的函数f(x),求[L,R]内有多少个数满足f(x)是真。其中一般L,R<=1e7L,R<=1e7或更大,且f(x)与数位相关。
本题中,用dp[i][j]代表考虑前i个数位,当前i位中有j个非零数位时,有多少个数满足条件。
这样我们就很容易处理[1,pow(10,t)]中的答案。
现在假设我们需要求[1,3812]的答案。当我们从第一位开始dfs时,从0遍历到3(最高位最大为3),如果第一位是0或1或2,则后面的数据无需考虑限制,都可以从0遍历到9。如果第一位是3,则第二位最大是8。我们使用数组上界变量代表这个限制,如果变量为0代表这一位无需考虑限制,否则代表这一位需要考虑限制。
代码
#include <iostream>
#include <cstring>
using namespace std;
typedef long long ll;
ll a[20];
ll dp[20][5];
ll dfs(ll pos, ll st, bool limit)
{
if(pos==-1) return 1;
if(!limit && dp[pos][st]!=-1) return dp[pos][st];
ll up=limit?a[pos]:9;
ll ans=0;
for(ll i=0;i<=up;i++)
{
if(i==0) ans+=dfs(pos-1,st,limit&&a[pos]==i);
else if(st!=3) ans+=dfs(pos-1,st+1,limit&&a[pos]==i);
}
if(!limit) dp[pos][st]=ans;
return ans;
}
ll solve(ll x)
{
ll tot=0;
//处理出每一位
while(x>0)
{
a[tot++]=x%10;
x/=10;
}
return dfs(tot-1,0,true);
}
int main()
{
memset(dp,-1,sizeof(dp));
ll T;
cin>>T;
while(T--)
{
ll l,r;
cin>>l>>r;
cout<<solve(r)-solve(l-1)<<endl;
}
return 0;
}