题意
求给定区间内 beautiful number 的数目
beautiful number :能被它自身非零位整除
思路
一个数字要被它的所有非零位整除,即被他们的LCM整除
若 x 为beautiful number
则有 x %LCM{DIGIT[xi]} == 0
⇒ x%MOD%LCM{DIGIT[xi]} == 0 其中 MOD为LCM{1…9}
我们可以记录DP[数位][num%MOD][num的LCM]
当且 num%MOD %num的LCM == 0 时 表示找到一个beautiful number
且 nextnum = num*10 +nextdigit
nextLCM = nextdigit ?LCM{num的LCM,nextdigit}:num的LCM
//nextdigit要不为零
这时我们可以拿三维数组存储结果 dp[20][2050][2050]
但是这样三维数组过大 无法运行
要将Num的LCM离散化
10以内最小公倍数组合 共有48种情况
故dp[20][2050][48]
这时就能存下了
接下来DFS解决
/*************************************************************************
> File Name: main.cpp
> Author:Chazz
> Created Time: 2015年11月04日 星期三 23时09分48秒
************************************************************************/
#include <iostream>
#include <cstdio>
#include <cstdlib>
#include <string.h>
#include <algorithm>
#include <vector>
#define MOD 2520
typedef long long ll;
using namespace std;
ll dp[21][MOD+5][55];
int inde[MOD+5];
int bit[20];
void init(){//初始化 且对NUM的LCM 离散化
int cnt = 0;
memset(dp,-1,sizeof(dp));
for(int i = 1;i <= MOD;i++){
if(MOD%i==0){
inde[i] = cnt++;
}
}
}
ll gcd(ll a,ll b){
return b==0?a:gcd(b,a%b);
}
ll lcm(ll a,ll b){
return a/gcd(a,b)*b;
}
ll dfs(int pos ,int presum,int prelcm,bool flag){
if(pos < 1){ //数位判断返回
return ( presum%prelcm == 0);
}
if(!flag && dp[pos][presum][inde[prelcm]]!=-1){
return dp[pos][presum][inde[prelcm]];
}
int end = flag?bit[pos]:9;
ll ans = 0;
for(int i = 0;i <= end;i++){
ans += dfs(pos-1,(presum*10+i)%MOD,i==0?prelcm:lcm(prelcm,i),flag&&i==end);
}
if(!flag){
dp[pos][presum][inde[prelcm]] = ans;
}
return ans;
}
ll solve(ll n){
int len = 0;
while(n){
bit[++len] = n%10;
n = n/10;
}
return dfs(len ,0,1,1);
}
int main(void){
int t;
init();
ll a,b;
cin>>t;
while(t--){
cin>>a>>b;
cout<<solve(b)-solve(a-1)<<endl;
}
return 0 ;
}