2 0 9 7604 24324
10 897
题意:找出区间内平衡数的个数,所谓的平衡数,就是以这个数字的某一位为支点,另外两边的数字大小乘以力矩 之和相等,即为平衡数
题解:枚举支点。一开始以为同一个数以不同的数位为支点会可能都是平衡数,这样就会算重复。然后仔细想想不可能
如果一开始以第一个为支点,左边为suml,支点右边为sumr,然后支点左移,suml是递减的,sumr是递增的。所以
不会重复。(0,00,000除外)
#include<cstdio>
#include<algorithm>
#include<cstring>
#include<iostream>
#include<cmath>
#define ll long long
#define N 1505
using namespace std;
ll l,r;
ll dp[20][20][N];///dp[i][j][k] i:长度 j:支点 k:和
int num[30];
ll dfs(int i,int z,int sum,bool e) {
if(i<=0)return sum==0;
if(sum<0)return 0;
if(!e&&dp[i][z][sum]!=-1)return dp[i][z][sum];
ll res=0;
int u=e?num[i]:9;
for(int d=0; d<=u; d++) {
int s=sum+(i-z)*d;
res+=dfs(i-1,z,s,e&&d==u);
}
return e?res:dp[i][z][sum]=res;
}
ll solve(ll n) {
int len=1;
while(n) {
num[len++]=n%10;
n/=10;
}
ll ans=0;
for(int i=1; i<=len-1; i++) {///枚举支点
ans+=dfs(len-1,i,0,1);
}
return ans-len+1;
}
int main() {
memset(dp,-1,sizeof dp);
int t;
cin>>t;
while(t--) {
scanf("%lld%lld",&l,&r);
printf("%lld\n",solve(r)-solve(l-1));
}
return 0;
}
原文地址:http://blog.csdn.net/acm_baihuzi/article/details/45225163