http://www.lightoj.com/volume_showproblem.php?problem=1068
类型:数位DP
1 #include <cstdio> 2 #include <algorithm> 3 #include <cstring> 4 using namespace std; 5 #define ll unsigned int 6 ll dp[83][11][83][83],md[12]={1}; 7 void init() 8 { 9 memset(dp,0,sizeof(dp)); 10 for(int i=1;i<11;i++) 11 md[i]=10*md[i-1]; 12 for(int k=1;k<83;k++) 13 for(int i=0;i<10;i++) 14 dp[k][1][i%k][i%k]++; 15 for(int k=2;k<83;k++) 16 for(int i=2;i<11;i++) 17 for(int j=0;j<k;j++) 18 for(int l=0;l<k;l++) 19 for(int m=0;m<10;m++){ 20 int tmp1=(m*md[i-1])%k; 21 int tmp2=m%k; 22 dp[k][i][j][l]+=dp[k][i-1][(k+j-tmp2)%k][(k+l-tmp1)%k]; 23 } 24 } 25 void print() 26 { 27 for(int k=2;k<5;k++) 28 for(int i=1;i<3;i++) 29 for(int j=0;j<k;j++) 30 for(int l=0;l<k;l++) 31 printf("k=%d i=%d j=%d l=%d ans=%d\n",k,i,j,l,dp[k][i][j][l]); 32 } 33 ll solve(ll x,ll k) 34 { 35 ll dig[15],cnt=0,ans=0; 36 while(x){ 37 dig[++cnt]=x%10; 38 x/=10; 39 } 40 ll sum=0,mul=0; 41 for(int i=cnt;i>1;i--){ 42 for(int j=0;j<dig[i];j++){ 43 ll tmp1=(sum+j)%k; 44 ll tmp2=(mul+j*md[i-1])%k; 45 ans+=dp[k][i-1][(k-tmp1)%k][(k-tmp2)%k]; 46 } 47 48 sum=(sum+dig[i])%k; 49 mul=(mul+dig[i]*md[i-1])%k; 50 } 51 for(int i=0;i<dig[1];i++) 52 if((mul+i)%k==0&&(sum+i)%k==0) 53 ans++; 54 return ans; 55 } 56 int main() 57 { 58 init(); 59 int t,cas=1; 60 scanf("%d",&t); 61 while(t--){ 62 ll l,r,k; 63 scanf("%d%d%d",&l,&r,&k); 64 printf("Case %d: ",cas++); 65 if(k==1) 66 printf("%d\n",r-l+1); 67 else if(k>82) 68 printf("0\n"); 69 else 70 printf("%u\n",solve(r+1,k)-solve(l,k)); 71 } 72 return 0; 73 }