hdu3652B-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
13 100 200 1000
 

 

Sample Output
1 1 2 2
 

 

Author
wqb0039
 

 

Source
2010 Asia Regional Chengdu Site —— Online Contest
 

 题解:

设f[i][j][r][0/1]表示i位数(可含前导0)第一位为j,mod13的余数是r,有没有出现13(0/1)的数有几个

code:

 1 #include<cstdio>
 2 #include<iostream>
 3 #include<cmath>
 4 #include<cstring>
 5 #include<algorithm>
 6 using namespace std;
 7 const int maxl=12;
 8 const int maxnum=10;
 9 const int rest=13;
10 int n,power[maxl],f[maxl][maxnum][rest][2],a[maxl];
11 void init(){
12     power[1]=1;
13     for (int i=2;i<=11;i++) power[i]=power[i-1]*10%13;
14     f[0][0][0][0]=1;
15     for (int i=1;i<=11;i++) for (int j=0;j<=9;j++)
16         for (int k=0;k<=9;k++) for (int r=0;r<13;r++){
17             int tmp=(r+j*power[i])%13;
18             if (!(j==1&&k==3)) f[i][j][tmp][0]+=f[i-1][k][r][0];
19             else f[i][j][tmp][1]+=f[i-1][k][r][0];
20             f[i][j][tmp][1]+=f[i-1][k][r][1];
21         }
22 }
23 int calc(int n){
24     int ans=0,t=n,len=0,r=0,tmp;
25     bool flag=0;
26     memset(a,0,sizeof(a));
27     while (t) a[++len]=t%10,t/=10;
28     for (int i=len;i;i--){
29         for (int j=0;j<a[i];j++){
30             tmp=((13-(r+j*power[i]))%13+13)%13;
31             for (int k=0;k<=9;k++) ans+=f[i-1][k][tmp][1];
32             if (!flag){
33                 if (a[i+1]==1){if (j==3) for (int k=0;k<=9;k++) ans+=f[i-1][k][tmp][0];}
34                 if (j==1) ans+=f[i-1][3][tmp][0];
35             }
36             else for (int k=0;k<=9;k++) ans+=f[i-1][k][tmp][0];
37         }
38         r+=a[i]*power[i],r%=13;
39         if (a[i+1]==1&&a[i]==3) flag=1;
40     }
41     return ans;
42 }
43 int main(){
44     init();
45     while (~scanf("%d",&n)) printf("%d\n",calc(n+1));
46     return 0;
47 }

 

你可能感兴趣的:(hdu3652B-number)