【HDU 3652】B-number
2016-05-07 08:49
253 查看
B-number
Time Limit: 2000/1000 MS (Java/Others) Memory Limit: 32768/32768 K (Java/Others)
Total Submission(s): 4096 Accepted Submission(s): 2335
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
[题意][计算在1-n中各位上的数字之和是13的倍数且含有13的数的个数]
【题解】【数位dp】
【f[i][j][k]:代表i位数开头为j.k=0代表含有‘13’的情况; k=1代表不含‘13’且首位不为3的情况; k=2代表不含‘13’且首位为3的情况】
【依据 a%13+b%13=j==(a+b)%13转移】
【这其实是数位dp较为经典的写法】
Time Limit: 2000/1000 MS (Java/Others) Memory Limit: 32768/32768 K (Java/Others)
Total Submission(s): 4096 Accepted Submission(s): 2335
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
[题意][计算在1-n中各位上的数字之和是13的倍数且含有13的数的个数]
【题解】【数位dp】
【f[i][j][k]:代表i位数开头为j.k=0代表含有‘13’的情况; k=1代表不含‘13’且首位不为3的情况; k=2代表不含‘13’且首位为3的情况】
【依据 a%13+b%13=j==(a+b)%13转移】
【这其实是数位dp较为经典的写法】
#include<cstdio> #include<cstring> #include<algorithm> #define ll long long using namespace std; ll f[20][20][3],h[20],tot,mi[20]; ll n; inline void dp() { f[0][0][1]=1; int i,j,k; for(i=0;i<10;++i) { f[1][i%13][0]=0; if(i!=3) f[1][i%13][1]=1; if(i==3) f[1][i%13][2]=1; } int a,amod,bmod; for(k=2;k<=10;++k)//枚举位数 for(i=0;i<13;++i)//枚举余数 for(j=0;j<10;++j)//枚举当前位可能出现的数字 { a=j*mi[k-1]; amod=a%13; bmod=((i-amod)%13+13)%13;//a%13+b%13=j==(a+b)%13 f[k][i][0]+=f[k-1][bmod][0];//继承 if(j==1) f[k][i][0]+=f[k-1][bmod][2];//若当前位是1,则继承上一位是3的情况 if(j!=3)//当前不需要更新f[i][j][2] { f[k][i][1]+=f[k-1][bmod][1];//继承 if(j!=1) f[k][i][1]+=f[k-1][bmod][2];//如果当前为不是1,则依旧不含13,所以继承上一位是3的情况 } if(j==3) f[k][i][2]+=f[k-1][bmod][2]+f[k-1][bmod][1];//如果当前位是3,则继承前面所有不含13的情况 } } inline ll math(ll n) { memset(h,0,sizeof(h)); tot=0; while(n) h[++tot]=n%10,n/=10; ll ans=0,amod=0,bmod=0,last=0,a=0; ll i,j; bool t=false; for(i=tot;i>0;--i) { for(j=0;j<h[i];++j) { a=last+mi[i-1]*j; amod=a%13; bmod=((0-amod)%13+13)%13; ans+=f[i-1][bmod][0]; }//加上以上一位为开头并且含有13的情况 if(t) { for(j=0;j<h[i];++j) { a=last+mi[i-1]*j; amod=a%13; bmod=((0-amod)%13+13)%13; ans+=f[i-1][bmod][1]+f[i-1][bmod][2]; } last+=h[i]*mi[i-1]; continue; }//如果前一位是3,当前位是1 if(h[i+1]==1&&h[i]>3)//如果上一位是1,且当前位可以取到3,所以加上当前位是3且不含13的情况 { a=last; amod=a%13; bmod=((0-amod)%13+13)%13; ans+=f[i][bmod][2]; } if(h[i]>1)//当前位某>1,说明可以出现13,即前一位可以是3 { a=last+mi[i-1]; amod=a%13; bmod=((0-amod)%13+13)%13; ans+=f[i-1][bmod][2]; } if(h[i]==3&&h[i+1]==1) t=true; last+=h[i]*mi[i-1]; } return ans; } int main() { mi[0]=1; for(int i=1;i<=10;++i) mi[i]=mi[i-1]*10; dp(); while(scanf("%I64d",&n)!=EOF) printf("%I64d\n",math(n+1)); return 0; }
相关文章推荐
- android基础总结篇之四:Service完全解析
- 51+TA8435h驱动步进电机经过光耦后出现的问题
- 安卓异常android.os.networkonmainthreadexception的解决方法
- XP系统开机到滚动条时就会重启怎么办?XP开机到滚动条时会重启电脑的解决方法
- Restful风格的curd
- Android Lollipop (5.0) 原生代码 Settings 首页加载逻辑分析
- 剑指Offer 面试题39:二叉树的深度(高度)(二叉树深度优先遍历dfs的应用) 题解
- 《key+》如何把密码安全的告诉对方
- hdu1070 milk 贪心
- 2016读书记录
- protobuf的C简单的代码例子(二)
- Android 切换系统语言源码分析
- 关于scanf,gets
- 手把手教你扩展个人微信号(1)
- 剑指offer 面试题47:不用+、-、×、÷做加法 题解
- 持续交付之二——配置管理
- Ubuntu搭建Openstack平台(kilo)(五.neutron(一)控制节点)
- 从零开始熟悉AS中手机app的开发(一)
- 安卓中app与service之间交互的五种方式
- Android Settings开发之修改