HDU

来源:互联网 发布:便签的元数据已损坏 编辑:程序博客网 时间:2024/06/08 12:12

B-number



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
131002001000
 

Sample Output
1122
 


题意:1~N中,含有13且能被13整除的数的个数


解题思路:经典的数位DP,难点在于怎么判断当前数能否被13整除。



#include<iostream>#include<deque>#include<memory.h>#include<stdio.h>#include<map>#include<string.h>#include<algorithm>#include<vector>#include<math.h>#include<stack>#include<queue>#include<set>using namespace std;typedef long long int ll;ll dp[30][10][2][20];//当前位为第i位,第i位的数字为j时,前面是否有13,前面数字组成的数余数为k时的个数。int dig[30];//保存数字的每一位ll dfs(int pos,int num,bool limit,bool have,int mod){    if(pos==-1)        return have&&mod==0;//如果有13且余数为0(能被13整除),返回1    //记忆化搜索    if(!limit && dp[pos][num][have][mod]!=-1)        return dp[pos][num][have][mod];    //循环遍历下一位的每一个数字,end记录最大能达到的数    int end=limit?dig[pos]:9;    ll ans=0;    for(int i=0;i<=end;i++){        int modx=(mod*10+i)%13;//其实就是除法的过程,学到了……        if((num==1&&i==3)){            ans+=dfs(pos-1,i,limit&&(i==end),1,modx);        }        else{            ans+=dfs(pos-1,i,limit&&(i==end),have,modx);        }    }    if(!limit)        dp[pos][num][have][mod]=ans;    return ans;}ll solve(ll x){    int pos=0;    while(x){        dig[pos++]=x%10;        x/=10;    }    return dfs(pos-1,0,1,0,0);}int main(){int n;    while(scanf("%lld",&n)!=EOF){                memset(dp,-1,sizeof(dp));        printf("%lld\n",solve(n));    }    return 0;}






原创粉丝点击