HDU 3652 B-number
来源:互联网 发布:测试脸型软件 编辑:程序博客网 时间:2024/05/16 12:04
B-number
Time Limit: 2000/1000 MS (Java/Others) Memory Limit: 32768/32768 K (Java/Others)Total Submission(s): 1813 Accepted Submission(s): 990
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
131002001000
Sample Output
1122
Author
wqb0039
Source
2010 Asia Regional Chengdu Site —— Online Contest
Recommend
lcy | We have carefully selected several similar problems for you: 3655 3654 3653 3659 3658
题意:有一个数N, 找出[1, N] 中的整数, 存在13, 并且能整除13的个数。
思路: 数位DP 在HDU 3555 基础上, 加多一个状态。就是mod.
不同于网上的 记忆化搜索,我比较喜欢用迭代。 思路比较清晰。
附2000以内的数, 13, 130, 1131, 1300, 1313, 1326, 1339, 1352, 1365, 1378, 1391。 11个。
原理。
所以i = 4的时候, 是衔接 0~5 和 (0~999 就是预处理dp[3][?][?]里)
所以i = 3的时候, 是衔接 0~1 和 (0~99 就是预处理dp[2][?][?]里)
所以i = 2的时候, 是衔接 0~2 和 (0~9 就是预处理dp[1][?][?]里)
所以i = 1的时候, 是衔接 0~8 和 (- 就是预处理dp[0][?][?]里)
#include <cstdio>#include <cstring>#include <algorithm>using namespace std;const int V = 10;const int mod= 13;int dp[V][mod][3], a;//dp[i][j][0~2], 长度为i的所有整数中,模13余j的(0: 无13, 1:无13,且最高位为3, 2:有13)的个数。int MOD[V]; //10^(V - 1) % 13void init() { //初始化MOD MOD[1] = 1; for(int i = 2; i < V; ++i) MOD[i] = (MOD[i - 1] * 10) % mod; // 初始化长度为0的情况。存在一个长度为0,余13为0的,不存在13的个数。 dp[0][0][0] = 1; // 初始化长度为1的情况。 只有10个数字。 for(int j = 0; j <= 9; ++j) dp[1][j][0] = 1; dp[1][3][1] = 1; // 往后转移状态 for(int i = 1; i < V - 1; ++i)//长度为i for(int j = 0; j < mod; ++j) // 模 for(int k = 0; k <= 9; ++k) { //i + 1位为k. int temp_j = (j + k * MOD[i + 1]) % mod; //算出对应的模。 //有多少就转移多少 dp[i + 1][temp_j][0] += dp[i][j][0]; dp[i + 1][temp_j][2] += dp[i][j][2]; if(k == 1) { //如果i + 1位加一,无13的情况, 要去掉第i位是3的, 并且有13的情况要加上第i位是3的。 dp[i + 1][temp_j][0] -= dp[i][j][1]; dp[i + 1][temp_j][2] += dp[i][j][1]; } if(k == 3) //如果i + 1 位加3, 则加上无13的数量。 dp[i + 1][temp_j][1] += dp[i][j][0]; }}int f(int a) { int bit[V], top = 0; int ans = 0; while(a) { bit[++top] = a % 10; a /= 10; } bool flag = false; int pre = 0; //记录之前出现的数字。 for(int i = top; i >= 1; --i) { for(int j = 0; j < bit[i]; ++j) { int temp_mod = (13 - (pre * 10 + j) * MOD[i] % mod) % mod; //计算下以为对应的模。 ans += dp[i - 1][temp_mod][2]; if(flag || j == 3 && pre % 10 == 1) //如果已经出现了13了 ans += dp[i - 1][temp_mod][0]; else if(j == 1) ans += dp[i - 1][temp_mod][1]; } pre = (pre * 10) + bit[i]; if(i != top && bit[i + 1] == 1 && bit[i] == 3) //判断是否已经出现了13. flag = true; } return ans;}int main() { init(); while(~scanf("%d", &a)) printf("%d\n", f(a + 1));}
1 0
- HDU 3652 B-number
- HDU 3652 B-number
- hdu 3652 B-number
- HDU 3652 B-number
- HDU 3652 B-number
- HDU-3652 B-number
- HDU 3652 B-number
- HDU 3652 B-number
- HDU 3652 B-number
- HDU 3652 B-number
- HDU 3652 B-number
- hdu 3652 B-number
- hdu 3652 B-number
- [hdu 3652] B-number
- HDU 3652 - B-number
- HDU 3652 B-number
- HDU 3652 B-number
- HDU 3652 B-number
- Linux 句柄是什么 ?
- 1011. World Cup Betting (20)
- What Do I Want To Learn?
- 1009. Product of Polynomials (25)
- delphi的消息列表
- HDU 3652 B-number
- 1008. Elevator (20)
- 亚当理论-十条准则
- 1007. Maximum Subsequence Sum (25)
- 如何彻底删除QQ程序
- xcode创建一个工程的多个taget,便于测试和发布多个版本
- hdu 1251 统计难题 字典树
- 经典代码 iFrame 自适应高度,在IE6/IE7/IE8/Firefox/Opera/Chrome/Safari通过测试。
- 1006. Sign In and Sign Out (25)