[HDU_3652]B-number

题目描述

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.

输入

 

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

 

 

输出

Print each answer in a single line.

样例输入

13
100
200
1000

样例输出

1
1
2
2

求小于n是13的倍数且含有“13”的数的个数,有多组数据,输入到结束。

dp[i][j][k][l]。i表示i位数j表示第i位是j的k表示是否包含13(k==0 or 1)L表示膜13是l的数的个数
#include<iostream>
#include<cstdio>
#include<cmath> 
using namespace std;
int dp[13][13][2][13];
int e[13];
void init()
{
    e[0]=1;
    for(int i=1;i<=10;i++)e[i]=(e[i-1]*10)%13;
    dp[0][0][0][0]=1;
    for(int i=1;i<=10;i++)
    for(int j1=0;j1<=9;j1++)
    for(int j2=0;j2<=9;j2++)
    for(int l=0;l<13;l++)
    {
        int yu=(l-(j1*e[i-1])%13+13)%13;//yu表示dp[][][][l]从dp[][][][yu]转移//yu+j1贡献的余数=l
        dp[i][j1][1][l]+=dp[i-1][j2][1][yu];
        if(j1==1&&j2==3)dp[i][j1][1][l]+=dp[i-1][j2][0][yu];
        else dp[i][j1][0][l]+=dp[i-1][j2][0][yu];
    }
 } 
int solve(int a)
{
    int len=0,ans=0,mod=0,d[12];bool t=0;
    while(a)
    {
        d[++len]=a%10;a/=10;
    }
    d[len+1]=0;
    for(;len>=1;len--)
    {
        for(int i=0;i<d[len];i++)
        {
            int yu=(13-(mod*e[len])%13)%13;//算上高位mod13的余数还要加多少(yu)mod13才会得0
            ans+=dp[len][i][1][yu];
            if(t||d[len+1]==1&&i==3)ans+=dp[len][i][0][yu];
        }
        if(d[len+1]==1&&d[len]==3)t=1;
        mod=(mod*10+d[len])%13;
    }
    return ans;
}
int main()
{
    int n;init();
    while(scanf("%d",&n)!=EOF)
    {
        printf("%d\n",solve(n+1));
    }
    return 0;
}
 
posted @ 2017-04-05 21:50  lher  阅读(147)  评论(0)    收藏  举报