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
题目大意:求[1,n]中有几个数包含13且是13的倍数
思路:数位DP,dp数组记录三个状态len长度,st包含13的状态(0是不包含,1 前一位为1, 2 以及出现13) num为对13的余数
代码:
#include<stdio.h>
#include<string.h>
#include<algorithm>
using namespace std;
int d[20],dp[20][3][15];
int fun(int st,int i)
{
if(st==0)
{
if(i==1) return 1;
return 0;
}
else if(st==1)
{
if(i==1)return 1;
else if(i==3) return 2;
return 0;
}
return 2;
}
int dfs(int len,int st,int num,int lim)
{
if(len==0) return num==0&&st==2;
if(!lim&&dp[len][st][num]!=-1) return dp[len][st][num];
int maxx=lim?d[len]:9,cnt=0;
for(int i=0;i<=maxx;i++)
cnt+=dfs(len-1,fun(st,i),(num*10+i)%13,lim&&i==maxx);
if(!lim) dp[len][st][num]=cnt;
return cnt;
}
int solve(int x)
{
int l=0;
while(x)
{
d[++l]=x%10;
x/=10;
}
return dfs(l,0,0,1);
}
int main()
{
int n;
memset(dp,-1,sizeof(dp));
while(~scanf("%d",&n))
{
printf("%d\n",solve(n));
}
return 0;
}