• 【HDU 3709】 Balanced Number (数位DP)


    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
    Author
    GAO, Yuan
    Source
     
     
    【题意】
     
        一个数n是平衡数当且仅当选一个位置j时,对于每一位(i-j)*a[i]的和为0,例如4139,4921,求l到r中有多少个平衡数(l<=r<=2^63-1)多组数据
     
    【分析】
     
      

      一开始纠结的地方呢就是一个数可不可能有两个平衡点。。然后就觉得会重复。
      用物理的思想想的话好像一个物体又没有两个重心??可是我不会用数学方法严谨证明ORZ。。。
      然后就是普通的数位DP,f[i][j][k]表示填i位j是平衡点,然后k是当前的计算值。(不超过4000)
      记忆化搜索大法好,又快又好打,特别是多组!!

      记得减掉00、000、0000的!

    代码如下:

     1 #include<cstdio>
     2 #include<cstdlib>
     3 #include<cstring>
     4 #include<iostream>
     5 #include<algorithm>
     6 #include<queue>
     7 #include<cmath>
     8 using namespace std;
     9 #define LL long long
    10 
    11 LL f[20][20][4010];
    12 int a[20],c;
    13 
    14 LL ffind(int n,int k,int sum,bool flag)
    15 {
    16     if(n==0) return (sum==0);
    17     if(!flag&&f[n][k][sum]!=-1) return f[n][k][sum];
    18     int ed=flag?a[n]:9;
    19     LL ans=0;
    20     for(int i=0;i<=ed;i++)
    21       ans+=ffind(n-1,k,sum+i*(k-n),flag&&(i==ed));
    22     if(!flag) f[n][k][sum]=ans;
    23     return ans;
    24 }
    25 
    26 LL get_ans(LL n)
    27 {
    28     if(n==-1) return 0;
    29     if(n==0) return 1;
    30     c=0;
    31     LL x=n;
    32     while(x) a[++c]=x%10,x/=10;
    33     LL ans=0;
    34     for(int i=1;i<=c;i++) ans+=ffind(c,i,0,1);
    35     return ans-c+1;
    36 }
    37 
    38 int main()
    39 {
    40     int T;
    41     scanf("%d",&T);
    42     memset(f,-1,sizeof(f));
    43     while(T--)
    44     {
    45         LL x,y;
    46         scanf("%lld%lld",&x,&y);
    47         get_ans(0);
    48         LL ans=get_ans(y)-get_ans(x-1);
    49         printf("%lld
    ",ans);
    50     }
    51     return 0;
    52 }
    [HDU 3709]

    感觉我没有判负就A了?!!

    2016-10-08 20:31:48

  • 相关阅读:
    OutputStream之flush() · 李大白写点儿啥
    AQS总结
    深入理解JavaScript中的this关键字
    Cookie
    【翻译】Ext JS 5的平板支持
    【翻译】在Sencha Touch中创建离线/在线代理
    OpenCV——PS 图层混合算法 (三)
    OpenCV——PS 图层混合算法 (二)
    【翻译】在Ext JS和Sencha Touch中创建自定义布局
    OpenCV——PS 图层混合算法(一)
  • 原文地址:https://www.cnblogs.com/Konjakmoyu/p/5940021.html
Copyright © 2020-2023  润新知