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



  • 相关阅读:
    sql 积分和消费,类似银行出入账单
    easyui datagrid选中当前行的index
    jquery 1+1=11 纠结死我了
    jquery 选择器
    easyui tree节点设置disabled的功能
    用户体验为什么如此重要?
    三个月内获得三年工作经验
    常用网站
    防呆设计
    读书笔记:启示录,打造用户喜爱的产品
  • 原文地址:https://www.cnblogs.com/chilumanxi/p/5136058.html
Copyright © 2011-2022 走看看