http://acm.hdu.edu.cn/showproblem.php?pid=4669
这题各种错误都来了一遍 预处理一下第一个数作为尾数与相邻前面的数组成的数的余数 然后再与后面的结合求余数
9 6 4 2 8
因为是个环 可以 9 6 4 2 8 9 6 4 2 8 组合 不过 又不能超N
所以先预处理 89 289 4289 64289 的余数 再与后面的组合 删除重复的
1 #include <iostream> 2 #include<cstdio> 3 #include<cstring> 4 #include<algorithm> 5 using namespace std; 6 #define N 50005 7 #define LL __int64 8 int dp[N][210]; 9 int b[N],di[N],pp[N*4]; 10 int digit(int x) 11 { 12 int i=0; 13 while(x) 14 { 15 i++; 16 x/=10; 17 } 18 return i; 19 } 20 int main() 21 { 22 int i,k,n,r,j; 23 while(scanf("%d%d",&n,&k)!=EOF) 24 { 25 for(i =0 ; i <= n ;i++) 26 for(j = 0; j < k ; j++) 27 dp[i][j] = 0; 28 for(i = 1; i <= n ; i++) 29 { 30 scanf("%d",&b[i]); 31 di[i] = digit(b[i]); 32 } 33 pp[0] = 1; 34 for(i = 1; i <= n*4 ; i++) 35 pp[i] = (pp[i-1]*10)%k; 36 int pre = 0; 37 b[n+1] = b[1]; 38 di[n+1] = di[1]; 39 r = 0; 40 for(i = n+1 ; i > 1 ; i--) 41 { 42 r = (b[i]*pp[pre]+r)%k; 43 pre+=di[i]; 44 dp[1][r]++; 45 } 46 int rr = r; 47 for(i = 2; i <= n ; i++) 48 { 49 for(r = 0 ; r < k ; r++) 50 { 51 int o = (r*pp[di[i]]+b[i])%k; 52 dp[i][o] += dp[i-1][r]; 53 } 54 rr = (rr*pp[di[i]]+b[i])%k; 55 dp[i][rr]--; 56 dp[i][b[i]%k]++; 57 rr = (rr-pp[pre]*b[i]+k)%k; 58 if(rr<0) rr+=k; 59 } 60 LL maxz=0; 61 for(i = 1; i <= n ; i++) 62 { 63 maxz+=dp[i][0]; 64 } 65 printf("%I64d ",maxz); 66 } 67 return 0; 68 }