思路:
简单的数位
取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; }