[暑假集訓--數位dp]hdu3652 B-number
阿新 • • 發佈:2017-08-04
spa scan make lin rom itl cst out code 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.
Output
Print each answer in a single line.
Input Process till EOF. In each line, there is one positive integer n(1 <= n <= 1000000000).
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> 7hdu 3652#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 namespacestd; 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 }
[暑假集訓--數位dp]hdu3652 B-number