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));
        }
    }
     
    
    
  • 相关阅读:
    mybatis中使用in查询时的注意事项
    单利模式
    jquery编写插件的方法
    python使用sendmail在linux下发送邮件
    python获取命令行输入参数列表
    互联网的实名与匿名
    Python切分字符串
    2017年3月15日留言 ——关于Java卡Applet系列csdn博文
    linux设置定时任务
    经典面试题:用户反映你开发的网站访问很慢可能会是什么原因
  • 原文地址:https://www.cnblogs.com/lonewanderer/p/5654629.html
Copyright © 2011-2022 走看看