平衡数は負でない整数であり、ピボットが特定の桁に配置されている場合に平衡化できます。より具体的には、各桁を、その桁で示される重みのあるボックスとして想像してください。ピボットが数値のある桁に配置されている場合、桁からピボットまでの距離は、その桁とピボットの間のオフセットです。次に、左側と右側のトルクを計算できます。それらが同じである場合、それはバランスが取れています。バランスの取れた数値は、その桁のいくつかでピボットとバランスをとる必要があります。たとえば、4139は、ピボットが3に固定された平衡数です。トルクは、左側と右側で、それぞれ4 2 + 1 1 = 9と9 * 1 = 9です。
与えられた範囲[x、y]でバランスの取れた数の数を計算するのはあなたの仕事です。
入力
入力には複数のテストケースが含まれています。最初の行は、ケースの総数T(0 <T≤30)です。いずれの場合も、行内のスペースで区切られた2つの整数xとyがあります。(0≤x≤y≤1018)。
出力
それぞれの場合について、[x、y]の範囲の平衡数の数を1行に出力します。
サンプル入力
2
0 9
7604 24324
サンプル出力
10
897
#include <stdio.h>
#include <string.h>
#include <math.h>
#include <map>
#include <stack>
#include <set>
#include <queue>
#include <vector>
#include <iostream>
#include <algorithm>
#include <cstring>
#include <string>
#include <cstdio>
#define ls (p<<1)
#define rs (p<<1|1)
#define ll long long
using namespace std;
const int maxn = 2e6+5;
const int INF = 0x3f3f3f3f;
ll dp[30][82][2010];
ll a[30];
ll dfs(int pos,int pre,int mo,bool limt){
//pre支点,力矩为mo
if(pos==0){
if(mo==0) return 1;
else return 0;
}
if(mo<0) return 0;
if(!limt&&dp[pos][pre][mo]!=-1)
return dp[pos][pre][mo];
ll up;
if(limt){
up=a[pos];
}
else up=9;
ll ans=0;
for(int i=0;i<=up;i++){
int tmp=mo+i*(pos-pre);
ans+=dfs(pos-1,pre,tmp,limt&&i==a[pos]);
}
if(!limt)
dp[pos][pre][mo]=ans;
return ans;
}
ll init(ll x){
if(x<0) return 0;
int len=0;
while(x){
a[++len]=x%10;
x/=10;
}
ll ans=0;
for(int i=1;i<=len;i++){
ans+=dfs(len,i,0,1);
}
return ans-len+1;
}
void solve(){
int t;
cin>>t;
memset(dp,-1,sizeof(dp));
memset(a,0,sizeof(a));
int cas=0;
while(t--){
ll n,m;
cin>>n>>m;
cout<<init(m)-init(n-1)<<endl;
}
}
int main()
{
ios::sync_with_stdio(false),cin.tie(0),cout.tie(0);
solve();
return 0;
}