• HDU 3652 B-number


    B-number

    Time Limit: 2000/1000 MS (Java/Others)    Memory Limit: 32768/32768 K (Java/Others)
    Total Submission(s): 3526    Accepted Submission(s): 1983


    Problem Description
    A wqb-number, or B-number for short, is a non-negative integer whose decimal form contains the sub- string "13" and can be divided by 13. For example, 130 and 2613 are wqb-numbers, but 143 and 2639 are not. Your task is to calculate how many wqb-numbers from 1 to n for a given integer n.
     

    Input
    Process till EOF. In each line, there is one positive integer n(1 <= n <= 1000000000).
     

    Output
    Print each answer in a single line.
     

    Sample Input
    13 100 200 1000
     

    Sample Output
    1 1 2 2
     

    题目大意是给定一个数字,求这个数字范围内的含有13的且可以被13整除的数的个数

    第一想法是跟Bomb那个题目一样去做,取一个fir_1找是否含有13的,但是做起来发现一个问题就是那个题目与这个题目差别在于当那个题目我知道有13以后,后面的数再取什么都可以不用管了,直接加上后面的数位的个数这么大的数量级就可以。但是对于这个题我们需要保存已经包含13这个数的这个状态,没有办法,只好升级维数,不过因为只有两个状态,所以空间并没有什么影响~

    构造这样一个dp[i][j][k][l]这么一个数组,i表示的是pos,j表示的是余数,k表示的是当前位上一位的数是否为1,l表示的是是否已经含有13。

    之后的处理比较简单,就是Bomb多了个取余的运算。

    代码如下:

    /*************************************************************************
    	> File Name: B-number.cpp
    	> Author: Zhanghaoran
    	> Mail: chilumanxi@xiyoulinux.org
    	> Created Time: Sat 14 Nov 2015 12:52:50 AM CST
     ************************************************************************/
    
    #include <iostream>
    #include <algorithm>
    #include <cstring>
    #include <cstdio>
    #include <cstdlib>
    
    using namespace std;
    
    long long x;
    long long dp[15][15][2][2];
    int num[15];
    long long work(int ,int ,int ,bool, bool);
    long long calc(long long x){
        int i = 1;
        while(x){
            num[i ++] = x % 10;
            x /= 10;
        }
        return work(i - 1, 0, 0, 0, 1);
    }
    
    long long work(int pos, int rem, int fir_1, bool fir_13, bool flag){
        if(pos == 0){
            if(fir_13 && !rem)
                return 1;
            else 
                return 0;
        }
    
        if(!flag && dp[pos][rem][fir_1][fir_13] != -1)
            return dp[pos][rem][fir_1][fir_13];
    
        long long ans = 0;
        int temp = flag ? num[pos] : 9;
        for(int i = 0; i <= temp; i ++){
            if(fir_13){
                ans += work(pos - 1, (rem * 10 + i) % 13, i == 1, 1, flag && i == temp);
            }
            else{
                if(fir_1 && i == 3)
                    ans += work(pos - 1, (rem * 10 + i) % 13, 0, 1, flag && i == temp);
                else 
                    ans += work(pos - 1, (rem * 10 + i) % 13, i == 1, 0, flag && i == temp);
            }
        }
    
        if(!flag && dp[pos][rem][fir_1][fir_13] == -1)
            dp[pos][rem][fir_1][fir_13] = ans;
        return ans;
    }
    
    int main(void){
        memset(dp, -1, sizeof(dp));
        while(~scanf("%lld", &x)){
            cout << calc(x) << endl;
        }
    }



  • 相关阅读:
    Python 正则表达式(分组)
    django 笔记
    Java代理和动态代理机制分析和应用
    Chrome浏览器如何调试移动端网页信息
    【数据分析】Excle中安装数据分析工具
    【BigData】Java基础_socket编程中使用多线程
    【BigData】Java基础_多线程
    【BigData】Java基础_socket编程
    财务报表之利润表
    资产负债表的会计恒等式
  • 原文地址:https://www.cnblogs.com/chilumanxi/p/5136058.html
Copyright © 2020-2023  润新知