崔老师给的一个叫做模版的东东。
B-number
Time Limit: 2000/1000 MS (Java/Others) Memory Limit: 32768/32768 K (Java/Others)Total Submission(s): 2145 Accepted Submission(s): 1154
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 <algorithm>
#include <iostream>
#include <stdlib.h>
#include <string.h>
#include <iomanip>
#include <stdio.h>
#include <string>
#include <queue>
#include <cmath>
#include <stack>
#include <map>
#include <set>
#define eps 1e-8
#define M 1000100
#define LL __int64
//#define LL long long
#define INF 0x3f3f3f3f
#define PI 3.1415926535898
const int maxn = 33;
using namespace std;
int dp[maxn][maxn][maxn];//代表前i位余数为j时候 flag的3种情况
int num[maxn];
int dfs(int pos, int pre, int flag, int bound)//pos代表位置,pre代表余数
{
int ans = 0, End, tflag, tpre;//flag 1代表上位是1,2代表前面已经有13了,0代表其他的。
if(pos == -1)
return pre == 0&&flag == 2;
if(!bound&&dp[pos][pre][flag] != -1)
return dp[pos][pre][flag];
End = bound ? num[pos] : 9;
for(int i = 0; i <= End; i++)
{
tpre = (pre*10+i)%13;
tflag = flag;
if(flag == 1 && i == 3)
tflag = 2;
else if(flag == 0 && i == 1)
tflag = 1;
else if(flag == 1 && i != 1)
tflag = 0;
ans += dfs(pos-1, tpre, tflag, bound&&i==End);
}
if(!bound)
dp[pos][pre][flag] = ans;
return ans;
}
int judge(int x)
{
int pos = 0;
while(x)
{
num[pos++] = x%10;
x /= 10;
}
return dfs(pos-1, 0, 0, 1);
}
int main()
{
int n;
memset(dp, -1, sizeof(dp));
while(~scanf("%d",&n))
printf("%d\n",judge(n));
return 0;
}