zoukankan      html  css  js  c++  java
  • 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)      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

    题意是给出一个范围,求出这个范围中的平衡数的数量,平衡数是指这个数各个位置中的每种偶数都出现了奇数次,每种奇数都出现了偶数次。(也都可以不出现)
    做法是用两个数t1, t2保存两种状态,t1保存(0~9)中的各个数字是否出现过,t2保存(0~9)中的各个偶数是否出现了奇数次,奇数是否出现了偶数次(先预处理)。这样子的话用(t1 & t2 == 0) 可以判断总的状态是否符合条件。显然t1、t2等于2 ^ 10 = 1024。
    并且注意这道题里翻转过来的数字的第一位是0的话也会影响答案,所以如果高位为0时向下传递初始的状态。我用zip表示了压缩的初始的状态,毕竟zip是压缩包嘛
    _(:з」∠)_,然后就是简单的搞数位dp了。

    #include <cstdio>
    #include <cstring>
    #include <algorithm>
    #include <iostream>
    #include <bitset>
    using namespace std;
    #define ll long long
    ll n, m;
    ll dp[20][1024][1024];
    int dig[20];
    int zip;
    
    void init() {
        for(int i = 0; i < 10; i += 2) zip ^= (1 << i);
        memset(dp, -1, sizeof(dp));
        /*bitset<10> btt(zip);
        cout << btt << endl;*/
    }
    
    void print(int num) {
        bitset<10> btt(num);
        cout << btt << endl;
    }
    
    ll dfs(int pos, int t1, int t2, int flag0, int lim) {
        //print(t1); print(t2); puts("");
        if(pos == -1) return (t1 & t2) == 0;
        if(!lim && dp[pos][t1][t2] != -1) return dp[pos][t1][t2];
        int End = lim ? dig[pos] : 9;
        ll ret = 0;
        for(int i = 0; i <= End; i++) {
            if(i == 0 && flag0) ret += dfs(pos - 1, 0, zip, 1, (i == End) && lim);
            else ret += dfs(pos - 1, t1 | (1 << i), t2 ^ (1 << i), 0, (i == End) && lim);
        }
        if(!lim) dp[pos][t1][t2] = ret;
        return ret;
    }
    
    ll func(ll num) {
        int n = 0;
        while(num) {
            dig[n++] = num % 10;
            num /= 10;
        }
        return dfs(n - 1, 0, zip, 1, 1);
    }
    
    int main() {
        init();
        int t;
        scanf("%d", &t);
        while(t--) {
            scanf("%I64d %I64d", &n, &m);
            printf("%I64d
    ", func(m) - func(n - 1));
        }
    }
     
    
    
  • 相关阅读:
    Select 多个表并且相关联转置
    Excel输入公式后只显示公式却不计算如何解决?
    Excel 下来公式 内容却一样
    MySQL数据迁移到SQL Server
    C# Excel 中设置文字对齐方式、方向和换行
    Response.write()弹出窗口的问题!
    ORA-12514 TNS 监听程序当前无法识别连接描述符中请求服务
    Hibernate中连接数据库的配置
    ERROR StatusLogger Log4j2 could not find a logging implementation. Please add log4j-core to the classpath. Using SimpleLogger to log to the console...
    帝国cms的tags页面url伪静态的设置
  • 原文地址:https://www.cnblogs.com/lonewanderer/p/5654629.html
Copyright © 2011-2022 走看看