• Balanced Number(数位DP)


    D - Balanced Number

     HDU - 3709

    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].

    InputThe 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 ≤ 10 18).OutputFor 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

    题意:找出区间内平衡数的个数,所谓平衡数,就是以这个数字的某一位为支点,左右两边的数字乘力矩之和相等。
    题解:比如4139
    digit 4 1 3 9
    len  4 3 2 1 对于每一位来说比如第四位4 for循环遍历这一位的数字就是0~4 对于第三位1来说就是遍历0~1。for循环遍历每一位作为支点,然后对于dfs中从最高位到最低位搜一遍,对于4139这个数来说,假设支点在2位置,len从4~1,sum=4*2+1*1+3*0+9*(-1)=0 所以4139是一个平衡数,sum=0,返回1。遍历完所有支点位置以及每一位从0到up,得到的和就是ans值。
     1 #include<iostream>
     2 #include<cstdio>
     3 #include<cstring>
     4 #include<algorithm>
     5 using namespace std;
     6 typedef long long ll;
     7 ll dp[20][20][2000];
     8 int digit[110];
     9 //dfs中4个参数,len代表当前所在的位数,zhou代表支点位置 
    10 //sum代表支点左边的数乘上力矩的加和-右边的数乘上力矩的加和
    11 //当sum为0时 代表以zhou这个位置为支点的存在一个数是平衡数。
    12 //limit代表的是每一位的上限 
    13 ll dfs(int len,int zhou,int sum,bool limit)
    14 {
    15     if(!len)
    16         return sum?0:1;
    17     if(!limit&&dp[len][zhou][sum]!=-1)
    18         return dp[len][zhou][sum];
    19     if(sum<0)
    20         return 0;
    21     int up=limit?digit[len]:9;
    22     ll ans=0;
    23     for(int i=0;i<=up;i++)
    24     {
    25         ans+=dfs(len-1,zhou,sum+i*(len-zhou),limit&&i==up);// sum+i*(len-zhou)表示当前的某一位上的某个数和它到支点距离的乘积 
    26     }
    27     if(!limit)
    28         dp[len][zhou][sum]=ans;
    29     return ans;
    30 }
    31 ll solve(ll x)
    32 {
    33     if(x<0)
    34         return 0;
    35     ll len=0;
    36     while(x)
    37     {
    38         digit[++len]=x%10;
    39         x/=10;
    40     } 
    41     ll ans=0;
    42     for(int i=len;i>0;i--)
    43     {
    44         ans+=dfs(len,i,0,true);
    45     }
    46     return ans-len+1;//因为0 00 000只能算一个 
    47 }
    48 int main()
    49 {
    50     int casen;
    51     cin>>casen;
    52     memset(dp,-1,sizeof(dp));
    53     while(casen--)
    54     {
    55         ll l,r;
    56         scanf("%lld%lld",&l,&r);
    57         printf("%lld
    ",solve(r)-solve(l-1));    
    58     } 
    59     return 0;
    60 } 

     

  • 相关阅读:
    装饰器
    闭包函数
    名称空间与作用域
    函数参数 函数对象 函数嵌套
    文件内光标的移动 函数基础 定义函数的三种形式 函数的返回值 调用方式
    文件
    字符编码 文件处理
    人月神话之阅读笔记一
    mysql+servlet+jsp实现数据库的增删改查
    文件与流课后作业
  • 原文地址:https://www.cnblogs.com/1013star/p/10322274.html
Copyright © 2020-2023  润新知