HDU 3652 B-number

B-number

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


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
 

 

Author
wqb0039
 

 

Source
 
/*第一道完全自己完全自己想出来的数位DP题*/
#include<stdio.h>
#include<iostream>
#include<string.h>
#include<algorithm>
#define N 14
using namespace std;
int dp[N][N][2][2],bit[N];//dp[len][r][m][s]表示当前搜到第len位,r是上一位的和模上13的值,
//搜到的数里是不是已经包含13了,当前位上是不是1
int dfs(int len,int r,int m,bool s,bool f)//当前搜到了第几位,上面搜到的结果模上13的余数,
{
    if(len<1)
        return ((!r)&&m)?1:0;
    if(!f&&dp[len][r][m][s]!=-1)
        return dp[len][r][m][s];
    int cur=0,fmax=f?bit[len]:9;
    for(int i=0;i<=fmax;i++)
        cur+=dfs(len-1,(r*10+i)%13,m||(s&(i==3)),i==1,f&&i==fmax);
    if(!f)
        dp[len][r][m][s]=cur;
    return cur;
}
int solve(int n)
{
    int len=0;
    while(n)
    {
        bit[++len]=n%10;
        n/=10;
    }
    return dfs(len,0,false,false,true);
}
int main()
{
    //freopen("in.txt","r",stdin);
    memset(dp,-1,sizeof dp);
    int n;
    while(scanf("%d",&n)!=EOF)
        printf("%d\n",solve(n));
    return 0;
}

 

 
 
posted @ 2016-08-11 15:53  勿忘初心0924  阅读(158)  评论(0编辑  收藏  举报