题目链接:https://vjudge.net/problem/HDU-3709

Balanced Number

Time Limit: 10000/5000 MS (Java/Others)    Memory Limit: 65535/65535 K (Java/Others)
Total Submission(s): 6615    Accepted Submission(s): 3174

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
 
Author
GAO, Yuan
 
Source

题解:

1.对于一个数,我们枚举每个位置作为平衡点,去判断是否存在一个位置使得这个数左右平衡。对于非0的数,如果它是平衡数,那么它的平衡点只有一个。(因为假设aaaa0bbb这个数的平衡点0,如果把平衡点往左移,那么左边变轻,右边变重,原本是平衡的,那改变之后就往右倾斜了。同理平衡点往右移。)所以是+1,正好一一对应。但是对于0,它的任意一个位置都可以作为平衡点,所以需要去重。

2. dp[pos][pivot][num]:处理到pos位置,以pivot为平衡点,且左力矩比右力矩大num的情况下,有多少种情况。

问:

1.为什么dp数组要有“pivot”这一维,直接:dp[pos][num]不行吗?

答:虽然有num记录了当前位的“左力矩 - 右力矩”的大小,但是如果两种情况的pivot不同,那么在pos后面的位置,他们的值的变化是不一样的,即这两种情况不是等价的。只有在相同的位置pos下,他们的平衡点pivot相同,且“左力矩 - 右力矩”的大小且相同,后面位置的数字变化才是等价的。

2.dp[pos][leftnum][rightnum] 这样记录不行吗?

答:其实这样跟dp[pos][num]的情况是一样的,都没有记录平衡点pivot的位置,导致后面位置的数值变化可能不等价。

代码如下:

 #include <iostream>
#include <cstdio>
#include <cstring>
#include <cstdlib>
#include <string>
#include <vector>
#include <map>
#include <set>
#include <queue>
#include <sstream>
#include <algorithm>
using namespace std;
typedef long long LL;
const double eps = 1e-;
const int INF = 2e9;
const LL LNF = 9e18;
const int MOD = 1e9+;
const int MAXN = 1e6+; int digit[];
LL dp[][][]; LL dfs(int pos, int pivot, int num, bool lim)
{
if(!pos) return (num==);
//剪枝,因为先加左边的,后减左边的,最终结果需要为0,如果过程中都出现负数,那减下去更加负,所以不可能符合条件
if(num<) return ;
if(!lim && dp[pos][pivot][num]!=-) return dp[pos][pivot][num]; LL ret = ;
int maxx = lim?digit[pos]:;
for(int i = ; i<=maxx; i++) //num+(pos-pivot)*i: 高位的加, 低位的减。这条式子很漂亮,刚好能满足力矩的计算
ret += dfs(pos-, pivot, num+(pos-pivot)*i, lim&&(i==maxx)); if(!lim) dp[pos][pivot][num] = ret;
return ret;
} LL solve(LL n)
{
int len = ;
while(n)
{
digit[++len] = n%;
n /= ;
} LL ret = ;
for(int i = ; i<=len; i++)
ret += dfs(len, i, , true); /*
为什么要减去len-1呢?原因是“0”这种情况,0在这里的表示是:000……00(len个0)。对于一个数
我们枚举每个位置作为平衡点,去判断是否存在一个位置使得这个数左右平衡。对于非0的数,如果
它是平衡数,那么它的平衡点只有一个,所以是+1,正好一一对应. 但对于000……00来说,它的每个
位置都可以作为平衡点( 因为左右两边都等于0),所以是+len,但是000……00却只是一个数,所以
需要减去重复计算的部分,即len-1.
*/
return ret-(len-);
} int main()
{
LL T, n, m;
scanf("%lld", &T);
memset(dp,-,sizeof(dp));
while(T--)
{
scanf("%lld%lld",&m,&n);
LL ans = solve(n) - solve(m-);
printf("%lld\n", ans);
}
return ;
}

最新文章

  1. Codeforces #380 Subordinates(贪心 构造)
  2. angular表单
  3. win7---远程桌面相关的服务
  4. 在浏览器中输入Google.com并且按下回车之后发生了什么(转载)
  5. qmake理解(还可以加入Lex Yacc文件)
  6. AFN演示
  7. (转)Spring读书笔记-----Spring的Bean之Bean的基本概念
  8. 提升ReSharper和Visual Studio的性能
  9. 如何调教Android Studio-Windows安装AS后的必备工作
  10. BigDecimal用法详解(转)
  11. 方法object面试题分析:7JAVA中Object的clone方法详解-克隆-深克隆
  12. RxSwift 系列(四) -- Transforming Operators
  13. LNMP环境的安装
  14. es6环境搭建
  15. Luogu 3371【模板】单源最短路径
  16. volatile的使用场景
  17. 关于模板引擎handlebars.js基本用法
  18. MarkDown 排版测试
  19. Jenkins报表 代码 指标分析
  20. AOP 环绕通知 集成了前置 后置 返回通知等功能

热门文章

  1. docker-nginx-标记一下
  2. What should do in Production
  3. codevs——T1860 最大数||洛谷——P1107 最大整数
  4. pyserial安装
  5. 济南day1
  6. BUPT复试专题—日期(2013)
  7. 转:给 Android 开发者的 RxJava 详解
  8. JAVA_MyEclipse常见配置NETGEAR路由器如何设置
  9. 【剑指offer】异或去重
  10. Objective-C之成魔之路【10-继承性】