1083: 完美数
Time Limit: 1 Sec Memory Limit: 128 MBSubmit: 208 Solved: 57
[ Submit][ Status][ Web Board]
Description
8是中国人很喜欢的一个数字,但是如果有3的存在就变成了38。。。就不是很好了。。 你能告诉我,在[L , R] 的正整数区间内,要么包含3 要么包含 8 的不同的整数有多少个么?
Input
第一行一个整数T(<=10000),代表数据的组数。 对于每组数据给两个整数 L , R (1 <= L <= R <= 1e9)。
Output
对于每组数据,给一个整数为答案。
Sample Input
3
1 100
1 3
8 8
Sample Output
3
4
1
1
分析:简单的数位DP
s=0表示既不含3也不含8
s=1表示只含3
s=2表示只含8
s=3表示既含3也含8
f[i][s]表示剩下i位满足s状态的总数
s=0表示既不含3也不含8
s=1表示只含3
s=2表示只含8
s=3表示既含3也含8
f[i][s]表示剩下i位满足s状态的总数
对于一个数比如7068,它存为a[]={8,6,0,7};
#include<cstdio>
#include<cstring>
int a[10],f[10][4];
int new_s(int s,int d){
if(d==3)return s|1;
if(d==8)return s|2;
return s;
}
int dfs(int i,int s,bool e){
if(i==-1)return s==1||s==2;
if(!e&&f[i][s]!=-1)return f[i][s];
int res=0,u=e?a[i]:9,d;
for(d=0;d<=u;d++)res+=dfs(i-1,new_s(s,d),e&&(d==u));
return e?res:f[i][s]=res;
}
int cal(int n){
int i=0;
while(n){a[i++]=n%10,n/=10;}
return dfs(i-1,0,1);
}
int main(){
int T,l,r;
scanf("%d",&T);
memset(f,-1,sizeof(f));
while(T--){
scanf("%d%d",&l,&r);
printf("%d\n",cal(r)-cal(l-1));
}
return 0;
}