B-number
Time Limit: 2000/1000 MS (Java/Others) Memory Limit: 32768/32768 K (Java/Others)Total Submission(s): 7409 Accepted Submission(s): 4340
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
#include <stdio.h>
#include<string.h>
#include<algorithm>
using namespace std;
int a[20];
int dp[20][20][3];//sta 为判断余数是否为0 sta1 0 不为1 1为1 2为 13
int dfs(int pos,int mod,int have,bool limit)//sta 为 mod sta1为数位判断
{
if(pos==-1)
return mod==0&&have==2;
if(dp[pos][mod][have]!=-1&&!limit)
return dp[pos][mod][have];
int up=limit?a[pos]:9;
int sum=0;
int have_x,i;
for(i=0;i<=up;i++)
{
have_x=have;
if(have_x==0&&i==1)
{
have_x=1;
}
if(have_x==1&&i==3)
{
have_x=2;
}
else if(have_x==1&&i!=1)
{
have_x=0;
}
sum+=dfs(pos-1,(mod*10+i)%13,have_x,limit&&i==up);
}
if(!limit)
{
dp[pos][mod][have]=sum;
}
return sum;
}
int solve(int x)
{
int cnt=0;
while(x)
{
a[cnt++]=x%10;
x/=10;
}
return dfs(cnt-1,0,0,1);
}
int main(int argc, char *argv[])
{
memset(dp,-1,sizeof(dp));
memset(a,-1,sizeof(a));
int n;
while(scanf("%d",&n)!=EOF)
{
printf("%d\n",solve(n));
}
return 0;
}