首页 > 代码库 > [暑假集训--数位dp]hdu3652 B-number

[暑假集训--数位dp]hdu3652 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.
 

 

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

 

数位dp

问 l 到 r 多少个数字是13倍数或者含有子串13

记一下当前的余数,是否已经是13倍数和上一位的数字大小

技术分享
 1 #include<cstdio>
 2 #include<iostream>
 3 #include<cstring>
 4 #include<cstdlib>
 5 #include<algorithm>
 6 #include<cmath>
 7 #include<queue>
 8 #include<deque>
 9 #include<set>
10 #include<map>
11 #include<ctime>
12 #define LL long long
13 #define inf 0x7ffffff
14 #define pa pair<int,int>
15 #define mkp(a,b) make_pair(a,b)
16 #define pi 3.1415926535897932384626433832795028841971
17 using namespace std;
18 inline LL read()
19 {
20     LL x=0,f=1;char ch=getchar();
21     while(ch<0||ch>9){if(ch==-)f=-1;ch=getchar();}
22     while(ch>=0&&ch<=9){x=x*10+ch-0;ch=getchar();}
23     return x*f;
24 }
25 LL n,len;
26 LL f[20][13][10][2];
27 int d[20];
28 inline int dfs(int now,int rest,int dat,int sat,int fp)
29 {
30     if (now==1)return !rest&&sat;
31     if (!fp&&f[now][rest][dat][sat]!=-1)return f[now][rest][dat][sat];
32     LL ans=0,mx=(fp?d[now-1]:9);
33     for (int i=0;i<=mx;i++)
34     {
35         if (sat||!sat&&dat==1&&i==3)ans+=dfs(now-1,(rest*10+i)%13,i,1,fp&&mx==i);
36         else ans+=dfs(now-1,(rest*10+i)%13,i,0,fp&&mx==i);
37     }
38     if (!fp&&f[now][rest][dat][sat]==-1)f[now][rest][dat][sat]=ans;
39     return ans;
40 }
41 inline LL calc(LL x)
42 {
43     LL xxx=x;
44     len=0;
45     while (xxx)
46     {
47         d[++len]=xxx%10;
48         xxx/=10;
49     }
50     LL sum=0;
51     for (int i=0;i<=d[len];i++)
52     sum+=dfs(len,i,i,0,i==d[len]);
53     return sum;
54 }
55 int main()
56 {
57     memset(f,-1,sizeof(f));
58     while (scanf("%d",&n)!=EOF)printf("%lld\n",calc(n));
59 }
hdu 3652

 

[暑假集训--数位dp]hdu3652 B-number