Balanced Number
Problem Description
A balanced number is a non-negative integer that can be balanced if a pivot is placed at some digit. More specifically, imagine each digit as a box with weight indicated by the digit. When a pivot is placed at some digit of the number, the distance from a digit to the pivot is the offset between it and the pivot. Then the torques of left part and right part can be calculated. It is balanced if they are the same. A balanced number must be balanced with the pivot at some of its digits. For example, 4139 is a balanced number with pivot fixed at 3. The torqueses are 4*2 + 1*1 = 9 and 9*1 = 9, for left part and right part, respectively. It's your job
to calculate the number of balanced numbers in a given range [x, y].
Input
The input contains multiple test cases. The first line is the total number of cases T (0 < T ≤ 30). For each case, there are two integers separated by a space in a line, x and y. (0 ≤ x ≤ y ≤ 1018).
Output
For each case, print the number of balanced numbers in the range [x, y] in a line.
Sample Input
2
0 9
7604 24324
Sample Output
10
897
题意:找出区间内平衡数的个数,所谓的平衡数,就是以这个数字的某一位为支点,另外两边的数字大小乘以力矩之和相等,即为平衡数。
对于这道题,如果一个数中每个数位到支点的距离*这个数位的和为0,那么这个数为平衡数.这样我们定义状态就要考虑力矩和和支点.支点可以在dfs前枚举得到,力矩和可以在处理每个数位的时候得到.但是这个算法是有缺陷的,例如0000,000000也会被统计,我们只需要减去给定范围0全是0的数的个数即可.这里可以进行一个小小的优化,如果力矩和已经为负数,说明已经处理到了支点左边,接着处理下去绝对会小于0,那么回溯即可.
#include<iostream>
#include<algorithm>
#include<cstdio>
#include<cstring>
#include<map>
#define N 0x3f3f3f3f
#define ll long long
using namespace std;
ll a[50];
ll dp[50][50][3000];
ll dfs(ll pos,ll zhiding,ll can,ll flag)
{
if(pos==0)
return can==0;
if(can<0)
return 0;
if(!flag&&dp[pos][zhiding][can]!=-1)
return dp[pos][zhiding][can];
ll ans=0;
int end=flag?a[pos]:9;
for(int i=0;i<=end;i++)
{
ll temp=can;
temp+=(pos-zhiding)*i;
ans+=dfs(pos-1,zhiding,temp,flag&&i==end);
}
if(!flag)
dp[pos][zhiding][can]=ans;
return ans;
}
ll solve(ll x)
{
int len=0;
ll ans=0;
while(x)
{
a[++len]=x%10;
x/=10;
}
for(int i=1;i<=len;i++)
{
ans+=dfs(len,i,0,1);
}
return ans-(len-1);
}
int main()
{
int t;
scanf("%d",&t);
memset(dp,-1,sizeof(dp));
while(t--)
{
ll r,l;
scanf("%lld%lld",&l,&r);
printf("%lld\n",solve(r)-solve(l-1));
}
return 0;
}