BALNUM - Balanced Numbers
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 both A 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:
2
1 1000
1 9
Output:
147
4
思路:数位dp+三进制状态压缩,0表示没出现过,1表示出现奇数次,2表示出现偶数次,下面给代码:
#include<cstdio>
#include<cstring>
#include<vector>
#include<queue>
#include<iostream>
#include<algorithm>
#include<cmath>
#include<bitset>
#include <utility>
using namespace std;
#define maxn 60000
typedef long long LL;
LL dp[25][maxn];
int digit[maxn][11];
int num[25];
int three[11] = { 1 };//three求出3的n次方
bool jud(int status){
for (int i = 0; i < 10; i++){
if (i & 1 && digit[status][i + 1] & 1)
return false;
else if (!(i & 1) && digit[status][i + 1] == 2)
return false;
}
return true;
}
int getstatus(int status,int now){
if (digit[status][now + 1] <= 1)
return status + three[now];
else
return status - three[now];
}
LL dfs(int pos, int status, int limit){
if (pos < 1){
return jud(status) ? 1 : 0;
}
if (!limit&&~dp[pos][status])
return dp[pos][status];
int end = limit ? num[pos] : 9;
LL ans = 0;
for (int i = 0; i <= end; i++){
if (!i&&!status)
ans += dfs(pos - 1, 0, limit&&i == end);
else
ans += dfs(pos - 1, getstatus(status, i), limit&&i == end);
}
if (!limit)
dp[pos][status] = ans;
return ans;
}
LL solve(LL x){
int len = 0;
while (x){
num[++len] = x % 10;
x /= 10;
}
return dfs(len, 0, 1);
}
int main(){
memset(dp, -1, sizeof(dp));
for (int i = 1; i <= 10; i++){
three[i] = three[i - 1] * 3;
}
for (int i = 1; i<three[10]; i++){
int temp = i;
for (int j = 1; j<11; j++){
digit[i][j] = temp % 3;
temp /= 3;
if (!temp)
break;
}
}
int t;
scanf("%d", &t);
while(t--){
LL l, r;
scanf("%lld%lld", &l, &r);
printf("%lld\n", solve(r) - solve(l - 1));
}
}