题意:给你N个珠宝和一个K,每个珠宝上面都有数字,这个珠宝做成项链,把珠宝上的数字拼起来如果可以整除掉K,那么久说这个数字为wonderful value,问你有多少种方案可以组成WONDERFUL VALUE。
对每个数取余并记录多少位,这样的话拼数的时候好操作。详细解法贴个结题报告吧。
代码:
1 #include <iostream> 2 #include <stdio.h> 3 using namespace std; 4 int dp[50005][300]; 5 int a[100005]; 6 int len[100005]; 7 int decmod[50005<<2]; 8 int digit(int a) 9 { 10 int len = 0; 11 12 while(a) 13 { 14 a /= 10; 15 len++; 16 } 17 18 return len; 19 } 20 void getdecmod(int k,int n) 21 { 22 decmod[0] = 1; 23 int i; 24 for(i = 1;i <= n<<2;i++) 25 { 26 decmod[i] = (decmod[i-1]*10)%k; 27 } 28 } 29 int main() 30 { 31 int n,k; 32 33 while(~scanf("%d %d",&n,&k)) 34 { 35 int j,i; 36 for(i = 1;i <= n;i++) 37 scanf("%d",&a[i]),a[i+n] = a[i]; 38 getdecmod(k,n); 39 for(i = 1;i <= n;i++) 40 { 41 for(j = 0;j < k;j++) 42 dp[i][j] = 0; 43 } 44 int r ; 45 for(i = 1;i <= n;i++) 46 { 47 len[i+n] = len[i] = digit(a[i]); 48 r = a[i] = a[i+n] = a[i]%k; 49 dp[i][r]++; 50 } 51 52 53 r = a[1]; 54 int sublen = 0; 55 for(i = n;i > 1;i--) 56 { 57 sublen += len[i+1]; 58 r = (a[i]*decmod[sublen]+r)%k; 59 dp[1][r]++; 60 61 } 62 sublen = 0; 63 for(i = 1;i<= n;i++) 64 sublen += len[i]; 65 int last; 66 last = r; 67 // printf("%d-------------- ",last); 68 __int64 ans = dp[1][0]; 69 for(i = 2;i <= n;i++) 70 { 71 for(j =0;j < k;j++) 72 { 73 r = (j*decmod[len[i]]+a[i])%k; 74 dp[i][r] += dp[i-1][j]; 75 } 76 last = (last*decmod[len[i]]+a[i])%k; 77 dp[i][last]--; 78 last = (last-(a[i]*decmod[sublen])%k+k)%k; 79 ans += dp[i][0]; 80 } 81 82 printf("%I64d ",ans); 83 } 84 }