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
核心思想:
数位dp模板题。
代码如下:
#include<cstdio>
#include<iostream>
using namespace std;
typedef long long ll;
const int N=11,M=13,K=3;
//dp[i][j][k]表示还有i位,高位的数对13取余为j
//k=2表示高位出现过13,否则,i+1位是1则k=1,是0则k=0
int dp[N][M][K],p[N];
int dfs(int pos,int mo,int k,int lim)
{
if(!pos)
return !mo&&k==2;//判断是否满足题目条件
if(!lim&&dp[pos][mo][k]!=-1)
return dp[pos][mo][k];
int end=lim?p[pos]:9;
int tm,tk,ans=0;
for(int i=0;i<=end;i++)
{
tm=(mo*10+i)%13;
if(k==2)
tk=2;
else if(k==1&&i==3)
tk=2;
else
tk=(i==1);
ans+=dfs(pos-1,tm,tk,lim&&i==end);
}
if(!lim)
return dp[pos][mo][k]=ans;
return ans;
}
int main()
{
int n;
//初始化
for(int i=0;i<N;i++)
for(int j=0;j<M;j++)
for(int z=0;z<K;z++)
dp[i][j][z]=-1;
//输入
while(scanf("%d",&n)!=EOF)
{
//按位拆分
int t=n,i=1;
while(t)
{
p[i++]=t%10;
t/=10;
}
//输出
printf("%d\n",dfs(i-1,0,0,1));
}
return 0;
}