zoukankan      html  css  js  c++  java
  • SPOJ

    链接:

    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.  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.

    思路:

    三进制记录每个值用的奇数次还是偶数次。
    直接DP即可。

    代码:

    // #include<bits/stdc++.h>
    #include<iostream>
    #include<cstdio>
    #include<vector>
    #include<string.h>
    #include<set>
    #include<queue>
    #include<algorithm>
    #include<math.h>
    using namespace std;
    typedef long long LL;
    typedef unsigned long long ULL;
    const int MOD = 1e9+7;
    const int MAXN = 1e6+10;
    
    ULL a, b;
    ULL F[21][60000];
    int dig[21];
    ULL m[11];
    
    int Upd(int x, int p)
    {
        int sum = 0;
        for (int i = 0;i < 10;i++)
        {
            int tmp = x%3;
            x /= 3;
            if (i == p)
                sum += (tmp == 1 ? 2 : 1) * m[i];
            else
                sum += tmp * m[i];
        }
        return sum;
    }
    
    bool Check(int x)
    {
        int p = 0;
        while(x)
        {
            if (x%3 == 2 && p%2 == 0)
                return false;
            if (x%3 == 1 && p%2 == 1)
                return false;
            x /= 3;
            p++;
        }
        return true;
    }
    
    ULL Dfs(int pos, int sta, bool zer, bool lim)
    {
        if (pos == -1)
            return Check(sta);
        if (!lim && F[pos][sta] != -1)
            return F[pos][sta];
        int up = lim ? dig[pos] : 9;
        ULL ans = 0;
        for (int i = 0;i <= up;i++)
        {
            ans += Dfs(pos-1, (zer && i == 0) ? 0 : Upd(sta, i), zer && i == 0, lim && i == up);
        }
        if (!lim)
            F[pos][sta] = ans;
        return ans;
    }
    
    ULL Solve(ULL x)
    {
        int p = 0;
        while(x)
        {
            dig[p++] = x%10;
            x /= 10;
        }
        return Dfs(p-1, 0, 1, 1);
    }
    
    int main()
    {
        // freopen("test.in", "r", stdin);
        m[0] = 1;
        for (int i = 1;i < 11;i++)
            m[i] = m[i-1]*3;
        memset(F, -1, sizeof(F));
        int t;
        scanf("%d", &t);
        while(t--)
        {
            scanf("%llu %llu", &a, &b);
            printf("%llu
    ", Solve(b)-Solve(a-1));
        }
    
        return 0;
    }
    
  • 相关阅读:
    团队冲刺-1
    最优惠购买书籍
    gogoing软件NABCD
    二维数组首尾相连
    首尾相连一维数组的最大子数组和
    二维数组返回最大子矩阵之和
    石家庄铁道大学基础教学楼电梯使用调查
    子数组最大值求和
    返回一个整数数组中最大子数组的和-课堂训练(子数组为连续)
    软件工程概论-四则运算
  • 原文地址:https://www.cnblogs.com/YDDDD/p/12000230.html
Copyright © 2011-2022 走看看