C - B-number

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;
}
发布了162 篇原创文章 · 获赞 18 · 访问量 2万+

猜你喜欢

转载自blog.csdn.net/weixin_43772166/article/details/103548663
今日推荐