思路:
简单的数位
取2表示出现过13,取1表示当前位是1,否则取0

状态:,长度为,当前数值的值为,状态是,这个状态是能保证结果唯一的

Code:

#include<iostream>
#include<cstdio>
#include<cstring>
#include<cmath>
#include<algorithm>
#include<queue>
#include <vector>
#include<map>
#include<set>
#include<utility>
using namespace std;
typedef long long ll;
inline ll read() {
    ll s = 0, w = 1;
    char ch = getchar();
    while (ch < 48 || ch > 57) {
        if (ch == '-') w = -1;
        ch = getchar();
    }
    while (ch >= 48 && ch <= 57)
        s = (s << 1) + (s << 3) + (ch ^ 48), ch = getchar();
    return s * w;
}
ll dp[11][3][13];
int digit[11];
ll dfs(int len,int pos,int sum,bool limit) {
    if(!len) {
        return (pos==2&&sum==0);
    }
    if(!limit&&dp[len][pos][sum]!=-1) return dp[len][pos][sum];
    int endi=(limit?digit[len]:9);
    ll ans=0;
    for(int i=0,tmp;i<=endi;++i) {
        if(i==1&&pos!=2) tmp=1;
        else if(pos==1&&i==3||pos==2) tmp=2;
        else tmp=0;
        ans+=dfs(len-1,tmp,(sum*10+i)%13,limit&&i==endi);
    }
    if(!limit) dp[len][pos][sum]=ans;
    return ans;
}
ll solve(ll x) {
    int len=0;
    while(x) {
        digit[++len]=x%10;
        x/=10;
    }
    return dfs(len,0,0,true);
}
int main() {
    ll n;
    memset(dp,-1,sizeof dp);
    while(~scanf("%lld",&n)) {
        printf("%lld\n",solve(n));
    }
    return 0;
}