题解:
设f[i][j][r][0/1]表示i位数(可含前导0)第一位为j,mod13的余数是r,有没有出现13(0/1)的数有几个
code:
1 #include<cstdio> 2 #include<iostream> 3 #include<cmath> 4 #include<cstring> 5 #include<algorithm> 6 using namespace std; 7 const int maxl=12; 8 const int maxnum=10; 9 const int rest=13; 10 int n,power[maxl],f[maxl][maxnum][rest][2],a[maxl]; 11 void init(){ 12 power[1]=1; 13 for (int i=2;i<=11;i++) power[i]=power[i-1]*10%13; 14 f[0][0][0][0]=1; 15 for (int i=1;i<=11;i++) for (int j=0;j<=9;j++) 16 for (int k=0;k<=9;k++) for (int r=0;r<13;r++){ 17 int tmp=(r+j*power[i])%13; 18 if (!(j==1&&k==3)) f[i][j][tmp][0]+=f[i-1][k][r][0]; 19 else f[i][j][tmp][1]+=f[i-1][k][r][0]; 20 f[i][j][tmp][1]+=f[i-1][k][r][1]; 21 } 22 } 23 int calc(int n){ 24 int ans=0,t=n,len=0,r=0,tmp; 25 bool flag=0; 26 memset(a,0,sizeof(a)); 27 while (t) a[++len]=t%10,t/=10; 28 for (int i=len;i;i--){ 29 for (int j=0;j<a[i];j++){ 30 tmp=((13-(r+j*power[i]))%13+13)%13; 31 for (int k=0;k<=9;k++) ans+=f[i-1][k][tmp][1]; 32 if (!flag){ 33 if (a[i+1]==1){if (j==3) for (int k=0;k<=9;k++) ans+=f[i-1][k][tmp][0];} 34 if (j==1) ans+=f[i-1][3][tmp][0]; 35 } 36 else for (int k=0;k<=9;k++) ans+=f[i-1][k][tmp][0]; 37 } 38 r+=a[i]*power[i],r%=13; 39 if (a[i+1]==1&&a[i]==3) flag=1; 40 } 41 return ans; 42 } 43 int main(){ 44 init(); 45 while (~scanf("%d",&n)) printf("%d\n",calc(n+1)); 46 return 0; 47 }