B-number
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,难点在于怎么判断当前数能否被13整除。
#include<iostream>
#include<algorithm>
#include<cstdio>
#include<cstring>
#include<map>
#define N 0x3f3f3f3f
#define ll long long
using namespace std;
int dp[20][20][10];
int a[20];
int dfs(int pos,int mod,int here,int flag)
{
if(pos<=0)// 这边需要注意你存储a的时候是从0 还是 1开始存的
// 小编是从1开始存的 如果你是从 0 开始存的 应该 写成 pos=-1
return mod==0&&here==2;// 符合条件
if(!flag&&dp[pos][mod][here]!=-1)
return dp[pos][mod][here];
int num=flag?a[pos]:9;
int sum=0;
for(int i=0;i<=num;i++)
{
int mod2=(mod*10+i)%13;
int here2=here;
if(here==0&&i==1)// 如果这位是1 那么标记一下 因为 它可以组成 13
here2=1;
if(here==1&&i!=1)// 如果前一位是1 且这一位不为1 那么here2=0 从新开始
here2=0;
if(here==1&&i==3)// 如果前一位是1 且这一位不为1 那么here2=2 已经存在了 13
here2=2;
sum+=dfs(pos-1,mod2,here2,flag&&i==num);
}
if(!flag)
{
dp[pos][mod][here]=sum;
}
return sum;
}
int main()
{
ll n;
memset(dp,-1,sizeof(dp));
while(cin>>n)
{
memset(a,0,sizeof(a));
int len=0;
while(n)
{
a[++len]=n%10;
n/=10;
}
int ans=dfs(len,0,0,1);
cout<<ans<<endl;
}
return 0;
}
看完这道题 可以看一下这道比较类似的题目 https://blog.youkuaiyun.com/henucm/article/details/83271790