标签:test long iostream -o you 一个 origin font space
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\n",solve(r)-solve(l-1));
58 }
59 return 0;
60 }
标签:test long iostream -o you 一个 origin font space
原文地址:https://www.cnblogs.com/1013star/p/10322274.html