此题在询问包含13的基本上还要求此数要整除13(如果连询问包含13的数位都不会的话,建议先看看更基础的这题 HDU 2089 不要62)
对于能否整除13,我们只需要在dfs的时候维护一个%13的数(num),然后在每次枚举下一位的时候num=(num*10+i)%13
最后只需要判断余数是否为0就可以了。
至于为什么可以这么做,因为:123=((1*10+2)*10+3)
所以:123%13=(((1*10+2)%13)*10+3)%13
代码如下:
#pragma comment(linker,"/STACK:1024000000,1024000000");
#include<algorithm>
#include<iostream>
#include<cstdlib>
#include<cstring>
#include<string>
#include<cstdio>
#include<climits>
#include<vector>
#include<queue>
#include<map>
#include<stack>
#include<cmath>
#define LL long long
#define INF 0x3f3f3f3f
#define MAXN 100000+24
const double eps = 1e-8;
using namespace std;
int t, n, k;
int digits[19];
LL dp[19][4][19];
LL dfs(int dex, int dt, int p, int num) {
LL ans = 0;
if (dex == 0) {
return dt == 2 && (num % 13 == 0);
}
if (dp[dex][dt][num] != -1 && !p) {
return dp[dex][dt][num];
}
int u = p ? digits[dex] : 9;
for (int i = 0; i <= u; i++) {
int nnum = (i + num * 10) % 13;
if (dt == 2 || dt == 1 && i == 3) ans += dfs(dex - 1, 2, p&&i == u, nnum);
else if ( i == 1) ans += dfs(dex - 1, 1, p&&i == u, nnum);
else ans += dfs(dex - 1, 0, p&&i == u, nnum);
}
if(!p) dp[dex][dt][num] = ans;
return ans;
}
LL digit(int num) {
k = 0;
while (num) {
digits[++k] = num % 10;
num /= 10;
}
return dfs(k, 0, 1, 0);
}
int main() {
#ifdef DID
freopen("in.txt", "r", stdin);
#endif
memset(dp, -1, sizeof(dp));
while (scanf("%d", &n) == 1) {
LL k1 = digit(n);
printf("%lld\n", k1);
}
return 0;
}