Codeforces Round#213(div.2)
C.Matrix
题意:
输入a和s。 s是只包含数字的字符串,b是一个矩阵,矩阵内的元素满足bij=si*sj。查找有多少个子矩阵,能满足这个子矩阵内的所有元素和为a。
思路:
注意一点:
子矩阵的横坐标、纵坐标上的数分别为(x,y,z,...)、(a,b,c,...),则子矩阵内元素和等于(a+b+c+...) * (x+y+z+...)。
由这点可将问题转化为求有多少种情况,令m*n==a。而m、n来自s的子串内digit之和。
因此枚举s的所有连续子串,保存下所有子串内digit和及个数。
当a不等于0时,枚举a的因子。
当a等于0时,只考虑num[0]。
PS:重复计算的情况为当横纵两数相等时 。
参考:http://blog.csdn.net/softshell/article/details/16838623
1 #include <iostream>
2 #include <cstring>
3 using namespace std;
4
5 #define N 40000
6 #define M 4010
7 long long num[N], digit[M];
8 char s[M];
9
10 int main()
11 {
12 long long a;
13 cin >> a >> s;
14 int len = strlen(s);
15 for(int i=0; i<len; i++)
16 {
17 digit[i+1] = s[i] - '0';
18 }
19 memset(num, 0, sizeof(num));
20 long long zero = 0;
21 for(int i=1; i<=len; i++)
22 {
23 long long temp = 0;
24 for(int j=i; j<=len; j++)
25 {
26 temp += digit[j];
27 num[temp]++;
28 zero++;
29 }
30 }
31 long long ans = 0;
32 //重复计算的情况为当横纵两数相等时
33 if(a==0)
34 {
35 ans = num[0] * zero * 2 - num[0]*num[0];
36 }
37 else
38 {
39 for(int i=1; i*i<=a; i++)
40 {
41 if(num[i]>0 && a/i<=N && a%i==0)
42 {
43 if(i * i == a)
44 ans += num[i] * num[i];
45 else
46 ans += num[i] * num[a/i] * 2;
47 }
48 }
49 }
50 cout << ans << endl;
51 return 0;
52 }
2 #include <cstring>
3 using namespace std;
4
5 #define N 40000
6 #define M 4010
7 long long num[N], digit[M];
8 char s[M];
9
10 int main()
11 {
12 long long a;
13 cin >> a >> s;
14 int len = strlen(s);
15 for(int i=0; i<len; i++)
16 {
17 digit[i+1] = s[i] - '0';
18 }
19 memset(num, 0, sizeof(num));
20 long long zero = 0;
21 for(int i=1; i<=len; i++)
22 {
23 long long temp = 0;
24 for(int j=i; j<=len; j++)
25 {
26 temp += digit[j];
27 num[temp]++;
28 zero++;
29 }
30 }
31 long long ans = 0;
32 //重复计算的情况为当横纵两数相等时
33 if(a==0)
34 {
35 ans = num[0] * zero * 2 - num[0]*num[0];
36 }
37 else
38 {
39 for(int i=1; i*i<=a; i++)
40 {
41 if(num[i]>0 && a/i<=N && a%i==0)
42 {
43 if(i * i == a)
44 ans += num[i] * num[i];
45 else
46 ans += num[i] * num[a/i] * 2;
47 }
48 }
49 }
50 cout << ans << endl;
51 return 0;
52 }