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
题解:https://blog.csdn.net/weixin_44554979/article/details/99603248
#include <cstdio>
#include <cstdlib>
#include <algorithm>
#include <iostream>
#include <cstring>
using namespace std;
typedef long long ll;
ll dp[110][15][3], x[110];//x保存数的每一位
ll v[110];
ll n;
ll dfs(int pos, int state, bool limit, int mod)//第pos位,上一位的数字,上一位是否为4,是否到达上限
{
ll sum = 0;
if (pos == -1)//这个数枚举完了
return state == 2 && mod == 0; //返回1表示是合法的
if (!limit && dp[pos][mod][state] != -1)//记忆化
return dp[pos][mod][state];
int up = (limit ? x[pos] : 9);//根据limit确定上限
for (int i = 0; i <= up; i++)//枚举,把不同情况的个数加到sum
{
int tmp = (mod * 10 + i) % 13;
if (state == 2){
sum += dfs(pos - 1, 2, limit && x[pos] == i, tmp);
}
else if (state == 1 && i == 3){
sum += dfs(pos - 1, 2, limit && x[pos] == i, tmp);
}
else if (i == 1){
sum += dfs(pos - 1, 1, limit && x[pos] == i, tmp);
}
else{
sum += dfs(pos - 1, 0, limit && x[pos] == i, tmp);
}
}
if(!limit)//记录状态
dp[pos][mod][state] = sum;
return sum;
}
ll f(ll t)
{
int pos = 0;
//memset(dp, -1, sizeof dp);
while (t)//提取每一位
{
x[pos++] = t % 10;
t /= 10;
}
return dfs(pos - 1, 0, true, 0);//从最高位开始递归
}
int main(void)
{
memset(dp, -1, sizeof(dp));
while (scanf("%lld", &n) != EOF)
{
printf("%lld\n", f(n));
}
return 0;
}