题目描述
我们称十进制形式包含子字符串 13 ,并且可以被 整除的数为B数。例如, 和 就是B数,而 和 不是。您的任务是计算 到 之间的B数个数。
输入格式
有多组数据,每组数据仅有一个正整数 。 数据以 EOF 结束。
输出格式
对于每一组数据,输出一个非负数,表示 到 之间的B数个数。
样例
输入样例
13
100
200
1000
输出样例
1
1
2
2
第一次写数位dp, 极其暴力,留个代码
(f_{i, j, k, l})表示从高到低枚举到第i位时, 状态为j(j==0表示啥都没有, 1表示只有1,2表示存在13),(k=0表示不可以自由放置,k=1表示可以放0-9任意一个数), l表示对13取模的值。、
上 代 码!!!!
#include <iostream>
#include <cstdio>
using namespace std;
const int N = 12;
int n = 10;
int number[N];
int f[N][3][2][13];
int pow[N];
int read(){
int num=0; char c=getchar();
while(!isdigit(c)) c=getchar();
while(isdigit(c)) num=num*10+c-'0', c=getchar();
return num;
}
void solve(){
for(int i=0; i<=n; i++){
for(int j=0; j<=2; j++){
for(int k=0; k<13; k++)
f[i][j][0][k] = f[i][j][1][k] = 0;
}
}
int flag = 0;
for(int i=0; i<=n; i++){
if(number[i] == 0 && flag==0){
f[i][0][0][0] = 1;
flag = 1;
continue;
}
for(int k=0; k<13; k++)
for(int j=0; j<=9; j++){
int m = (j*pow[i])%13;
int need = (k-m+13)%13;
if(j < number[i]){
f[i][2][1][k] += f[i-1][2][1][need] + f[i-1][2][0][need];
if(j == 1){
f[i][1][1][k] += f[i-1][1][0][need] + f[i-1][1][1][need] + f[i-1][0][1][need] + f[i-1][0][0][need];
}else if(j == 3){
f[i][2][1][k] += f[i-1][1][0][need] + f[i-1][1][1][need];
f[i][0][1][k] += f[i-1][0][1][need] + f[i-1][0][0][need];
}else{
f[i][0][1][k] += f[i-1][0][1][need] + f[i-1][0][0][need] + f[i-1][1][1][need] + f[i-1][1][0][need];
}
}else if(j == number[i]){
f[i][2][1][k] += f[i-1][2][1][need];
f[i][2][0][k] += f[i-1][2][0][need];
if(j == 1){
f[i][1][1][k] += f[i-1][0][1][need] + f[i-1][1][1][need];
f[i][1][0][k] += f[i-1][1][0][need] + f[i-1][0][0][need];
}else if(j == 3){
f[i][2][1][k] += f[i-1][1][1][need];
f[i][2][0][k] += f[i-1][1][0][need];
f[i][0][1][k] += f[i-1][0][1][need];
f[i][0][0][k] += f[i-1][0][0][need];
}else{
f[i][0][1][k] += f[i-1][0][1][need] + f[i-1][1][1][need];
f[i][0][0][k] += f[i-1][0][0][need] + f[i-1][1][0][need];
}
}else if(j > number[i]){
f[i][2][1][k] += f[i-1][2][1][need];
if(j == 1){
f[i][1][1][k] += f[i-1][0][1][need] + f[i-1][1][1][need];
}else if(j == 3){
f[i][2][1][k] += f[i-1][1][1][need];
f[i][0][1][k] += f[i-1][0][1][need];
}else{
f[i][0][1][k] += f[i-1][0][1][need] + f[i-1][1][1][need];
}
}
}
}
cout << f[n][2][0][0] + f[n][2][1][0] << endl;
}
int main(){
int x;
while(cin >> x){
for(int i=0; i<=n; i++) number[i] = 0;
int l = 1;
for(int i=n; i>=0; i--){
number[i] = x%10;
pow[i] = l;
l *= 10;
x /= 10;
}
solve();
}
return 0;
}