hdu 3652 B-number
2016-04-24 20:23
281 查看
B-number
Time Limit: 2000/1000 MS (Java/Others) Memory Limit: 32768/32768 K (Java/Others)Total Submission(s): 4070 Accepted Submission(s): 2321
[align=left]Problem Description[/align]
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.
[align=left]Input[/align]
Process till EOF. In each line, there is one positive integer n(1 <= n <= 1000000000).
[align=left]Output[/align]
Print each answer in a single line.
[align=left]Sample Input[/align]
13 100 200 1000
[align=left]Sample Output[/align]
1 1 2 2
[align=left]Author[/align]
wqb0039
[align=left]Source[/align]
2010 Asia Regional Chengdu Site —— Online Contest
[align=left]Recommend[/align]
lcy | We have carefully selected several similar problems for you: 3651 3655 3654 3653 3659
Statistic | Submit | Discuss
| Note
神奇的数位DP:
dp[i][j][0] 表示位数不超过i,余数为j的含13的个数
dp[i][j][1] 表示位数不超过i,余数为j的不含13且最高位为3的个数
dp[i][j][2] 表示位数不超过i,余数为j的不含13的个数
#include<iostream> #include<cstdio> #include<cstring> #include<algorithm> #include<cmath> using namespace std; int n,m,num[10],md[12]; int dp[20][20][20]; int sqr(int x,int y) { int t=1; for (int i=1;i<=y;i++) t=t*10; return t; } void calc() { md[0]=1; for (int i=1;i<=9;i++) md[i]=md[i-1]*10; memset(dp,0,sizeof(dp)); dp[0][0][2]=1; for (int i=0;i<=9;i++) { dp[1][i][0]=0,dp[1][i][2]=1,dp[1][i][1]=0; } dp[1][3][1]=1; for (int i=2;i<=9;i++) { int t=md[i-1]; for (int j=0;j<=9;j++) { int k=(t*j)%13; for (int l=0;l<=12;l++) { dp[i][(k+l)%13][0]+=dp[i-1][l][0]+(j==1?dp[i-1][l][1]:0); dp[i][(k+l)%13][1]+=(j==3?dp[i-1][l][2]:0); dp[i][(k+l)%13][2]+=dp[i-1][l][2]-(j==1?dp[i-1][l][1]:0); } } } } int solve(int x) { int d[11],len=0; for(int i=x;i;i/=10) d[len++]=i%10; d[len]=0; bool flag=false; int ans=0,mod=0; for(int i=len-1;i>=0;mod=(mod+d[i]*md[i])%13,i--) { for(int j=0;j<d[i];j++) ans+=dp[i][(13-(mod+j*md[i])%13)%13][0]; if(flag)//如果原数列中有13,那么之后的数就都是合法的 { for(int j=0;j<d[i];j++) ans+=dp[i][(13-(mod+j*md[i])%13)%13][2]; continue; } if(d[i+1]==1 && d[i]>3) ans+=dp[i+1][(13-mod)%13][1]; if(d[i]>1) ans+=dp[i][(13-(mod+md[i])%13)%13][1]; if(d[i+1]==1 && d[i]==3) flag=true; } return ans; } int main() { calc(); while (scanf("%d",&n)!=EOF) { int t=solve(n+1); printf("%d\n",t); } }
相关文章推荐
- 可复用且高度解耦的iOS用户统计实现
- 远程连接oracle数据库
- HDU 1266 Reverse Number(模拟or数字字符串)
- Linux下LAMP环境的搭建
- HDU5670Machine(抽象进制)
- Core Bluetooth的基本常识
- 安卓xml颜色设置
- 安卓xml颜色设置
- “Wishare杯”南邮第八届大学生程序设计竞赛之现场决赛 题解报告
- FZU 1202 信与信封问题
- 关于youtube上Android Performance Patterns的总结(部分)
- [算法] 生成唯一id
- caffe基础介绍
- 用java实践了下Bingo游戏的玩法
- C# 利用DotRas 操作adsl
- 加速计
- 324. Wiggle Sort II
- ext3文件系统超级块损坏修复
- 透视投影矩阵的一些概念
- 《Java程序设计》实验3