题目分析
给定一个区间,看有多少数是跳板数,跳板树的定义是选定数字中的某一位作为支撑点,那么左边距支撑点的距离乘以左边数字的大小等于右边距支撑点的距离乘以右边数字的大小,如果相等,则为跳板数。这道题也是很迷呀!!写了半天一直在想我在里面找跳板,后来看了一下别人的博客瞬间明白了,我可以在最外面找跳板,简单并且清晰,可能写题写傻了!!!
#include <cstdio>
#include <cstring>
#include <iostream>
#include <algorithm>
using namespace std;
typedef long long LL;
LL dp[20][20][2500],bit[20];
LL dfs(int pos,int pivot,int ans,int limit){
if(pos < 1) return ans == 0;
if(ans < 0) return 0;
if(!limit && dp[pos][pivot][ans] != -1) return dp[pos][pivot][ans];
LL ret = 0;
int len = limit?bit[pos]:9;
for(int i = 0; i <= len; i++){
ret += dfs(pos-1, pivot, ans+(pos-pivot)*i, limit&&i==len);
}
if(!limit) dp[pos][pivot][ans] = ret;
return ret;
}
LL solve(LL n){
int len = 0;
while(n){
bit[++len] = n%10;
n /= 10;
}
LL ret = 0;
for(int i = 1; i <= len; i++)
ret += dfs(len, i, 0, 1);
return ret-len+1; //减去没有用但是重复的0,00,000...
}
int main(){
int T;
scanf("%d", &T);
memset(dp, -1, sizeof(dp));
while(T--){
LL x,y;
scanf("%I64d %I64d", &x, &y);
if(x == 0) printf("%I64d\n", solve(y));
else printf("%I64d\n", solve(y) - solve(x-1));
}
return 0;
}