Balanced Numbers 数位DP+3进制压缩

来源:互联网 发布:王陆807和语料库 知乎 编辑:程序博客网 时间:2024/05/16 04:41

Balanced numbers have been used by mathematicians for centuries. A positive integer is considered a balanced number if:

1)      Every even digit appears an odd number of times in its decimal representation

2)      Every odd digit appears an even number of times in its decimal representation

For example, 77, 211, 6222 and 112334445555677 are balanced numbers while 351, 21, and 662 are not.

Given an interval [A, B], your task is to find the amount of balanced numbers in [A, B] where bothA and B are included.

Input

The first line contains an integer T representing the number of test cases.

A test case consists of two numbers A and B separated by a single space representing the interval. You may assume that 1 <= A <= B <= 1019 

Output

For each test case, you need to write a number in a single line: the amount of balanced numbers in the corresponding interval

Example

Input:21 10001 9
Output:1474

题意:求范围内 偶数出现奇数次,奇数出现偶数次的 数的 个数

思路:数位DP+3进制压缩。有3种状态(0:没出现过, 1:数字出现奇数次, 2:数字出现偶数次), 0~9 出现的次数就可以用3进制表示,最大的数就是 310 ,那么就可以把1019 哈希到310 内。dp[pos][sta]含义即 pos位的数字中有sta种方法数(hash过后的)。

Code:

#include <iostream>#include <string.h>#include <cstdio>#define LL long long using namespace std;int a[25];LL dp[25][60000];bool check( LL x ){for( int i = 0 ; i < 10 ; i++ ){if( (i&1) && (x%3==1) ) return false ;if( !(i&1) && (x%3==2) ) return false ;x /= 3;}return true;}LL hash( int sta , int i ){            //作用就是把i这个数字出现的次数奇偶性改变 得到新的sta(方法数)。int b[10]; for( int j = 0 ; j < 10 ; j++ ){b[j] = sta % 3 ;          //将sta转化3进制存储在b数组,分别对应每个数字出现的奇偶次数。sta /= 3;              }if( b[i] == 0 ) b[i] = 1 ;    //改变 i 的出现次数奇偶性(0:没出现过, 1:数字出现奇数次, 2:数字出现偶数次)else b[i] = 3 - b[i];for( int j = 9 ; j >= 0 ; j -- )  sta = sta * 3 + b[j];  //得到新的sta值return sta;}LL dfs( int pos , int sta , bool lead , bool limit ){if( pos == -1 ) return check(sta) ;if( !limit && dp[pos][sta] != -1 ) return dp[pos][sta];LL ans = 0 ;int up = limit ? a[pos] : 9 ;for( int i = 0 ; i <= up ; i++ ){if( lead && i == 0 ) ans += dfs( pos - 1 , sta , lead && i == 0 , limit && i == up);else ans += dfs( pos - 1 , hash( sta , i ) , lead && i == 0 , limit && i == up);}if( !limit ) dp[pos][sta] = ans ;return ans ;}LL solve( LL x ){int tot = 0 ;while( x ){a[tot++] = x % 10;x /= 10 ;}return dfs( tot - 1 , 0, true, true );}int main(){ios_base::sync_with_stdio(false); cin.tie(0);int T;cin >> T ;int l , r ;memset(dp,-1,sizeof(dp));while( T-- ){cin >> l >> r ;cout << solve(r) - solve(l-1) << endl;}return 0;}

阅读全文
0 0
原创粉丝点击