SPOJ10606---Balanced Numbers(三进制数位dp)

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

/*************************************************************************
    > File Name: spoj10606.cpp
    > Author: ALex
    > Mail: [email protected]
    > Created Time: 2015年02月28日 星期六 19时43分30秒
 ************************************************************************/

#include <map>
#include <set>
#include <queue>
#include <stack>
#include <vector>
#include <cmath>
#include <cstdio>
#include <cstdlib>
#include <cstring>
#include <iostream>
#include <algorithm>
using namespace std;

const double pi = acos(-1);
const int inf = 0x3f3f3f3f;
const double eps = 1e-15;
typedef long long LL;
typedef pair <int, int> PLL;

LL dp[30][60000];
int bit[30];
int three[20];
int S[30];

int getsta (int sta, int e)
{
    int ss = 0;
    memset (S, 0, sizeof(S));
    int cnt = 0;
    while (sta)
    {
        S[cnt++] = sta % 3;
        sta /= 3;
    }
    if ((++S[e]) == 3)
    {
        S[e] = 1;
    }
    for (int i = 0; i <= 9; ++i)
    {
        ss += S[i] * (three[i]);
    }
    return ss;
}

bool judge (int sta)
{
    memset (S, 0, sizeof(S));
    int cnt = 0;
    while (sta)
    {
        S[cnt++] = sta % 3;
        sta /= 3;
    }
    for (int i = 0; i <= 9; ++i)
    {
        if (!S[i])
        {
            continue;
        }
        if ((i & 1) != (S[i] & 1))
        {
            continue;
        }
        else
        {
            return 0;
        }
    }
    return 1;
}

LL dfs (int cur, int e, int sta, bool flag, bool zero)
{
    if (cur == -1)
    {
        if (zero)
        {
            return 0;
        }
        return judge (sta);
    }
    if (!flag && ~dp[cur][sta])
    {
        return dp[cur][sta];
    }
    LL ans = 0;
    int end = flag ? bit[cur] : 9;
    for (int i = 0; i <= end; ++i)
    {
        int newsta = getsta (sta, i);
        if (zero && !i)
        {
            ans += dfs (cur - 1, 0, 0, flag && (i == end), 1);
        }
        else if (zero && i)
        {
            ans += dfs (cur - 1, i, three[i], flag && (i == end), 0);
        }
        else
        {
            ans += dfs (cur - 1, i, newsta, flag && (i == end), 0);
        }
    }
    if (!flag)
    {
        dp[cur][sta] = ans;
    }
    return ans;
}

LL calc (int n)
{
    int cnt = 0;
    while (n)
    {
        bit[cnt++] = n % 10;
        n /= 10;
    }
    return dfs (cnt - 1, 0, 0, 1, 1);
}

int main ()
{
    int t;
    LL l, r;
    three[0] = 1;
    memset (dp, -1, sizeof(dp));
    for (int i = 1; i <= 9; ++i)
    {
        three[i] = 3 * three[i - 1];
    }
    scanf("%d", &t);
    while (t--)
    {
        scanf("%lld%lld", &l, &r);
        printf("%lld\n", calc (r) - calc (l - 1));
    }
    return 0;
}
时间: 2024-10-05 13:28:48

SPOJ10606---Balanced Numbers(三进制数位dp)的相关文章

Balanced Numbers数位dp

三进制搞下, 0  表示没出现过,  第i位为1 表示 i出现了奇数次,  2表示i 出现了偶数次. #include <cstdio> #include <cstring> #include <algorithm> #include <climits> #include <string> #include <iostream> #include <map> #include <cstdlib> #includ

SPOJ10606 BALNUM - Balanced Numbers(数位DP+状压)

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 numb

spoj Balanced Numbers(数位dp)

一个数字是Balanced Numbers,当且仅当组成这个数字的数,奇数出现偶数次,偶数出现奇数次 一下子就相到了三进制状压,数组开小了,一直wa,都不报re, 使用记忆化搜索,dp[i][s] 表示长度为i,状态为s,时,满足条件的balance number的个数 #include <stdio.h> #include <string.h> #include <stdlib.h> #include <algorithm> #include <io

SPOJ BALNUM Balanced Numbers(数位dp)

Balanced Numbers Time Limit:123MS     Memory Limit:1572864KB     64bit IO Format:%lld & %llu Submit Status Practice SPOJ BALNUM Description Balanced numbers have been used by mathematicians for centuries. A positive integer is considered a balanced n

spoj 10606 Balanced Numbers 数位dp

题目链接 一个数称为平衡数, 满足他各个数位里面的数, 奇数出现偶数次, 偶数出现奇数次, 求一个范围内的平衡数个数. 用三进制压缩, 一个数没有出现用0表示, 出现奇数次用1表示, 出现偶数次用2表示, 这样只需要开一个20*60000的数组. 1 #include<bits/stdc++.h> 2 using namespace std; 3 #define pb(x) push_back(x) 4 #define ll long long 5 #define mk(x, y) make_

SPOJ BALNUM Balanced Numbers(数位dp,状态压缩)

BALNUM - Balanced Numbers no tags 题目链接 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)   

SPOJ BALNUM Balanced Numbers 状压+数位DP

一开始想了一个用二进制状压的方法,发现空间需要的太大,光光memset都要超时 = = 其实不用每次都memset 也可以用三进制,一开始直接打表出所有的状态转移就好 #include <cstdio> #include <cstring> #include <cmath> #include <algorithm> #include <climits> #include <string> #include <iostream&g

SPOJ - BALNUM - Balanced Numbers(数位DP)

链接: https://vjudge.net/problem/SPOJ-BALNUM 题意: 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)

BALNUM - Balanced Numbers

BALNUM - Balanced Numbers Time limit:123 ms Memory limit:1572864 kB 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