牛客国庆集训派对Day2 Solution
A 矩阵乘法
思路:
1° 牛客机器太快了,暴力能过。
1 #include <bits/stdc++.h> 2 using namespace std; 3 4 #define N 5000 5 6 int n, p, m; 7 int a[N][100], b[100][N], ans[N][N]; 8 9 void Run() 10 { 11 while (scanf("%d%d%d", &n, &p, &m) != EOF) 12 { 13 for (int i = 1; i <= n; ++i) 14 for (int j = 1; j <= p; ++j) 15 scanf("%X", &a[i][j]); 16 for (int j = 1; j <= m; ++j) 17 for (int i = 1; i <= p; ++i) 18 scanf("%1d", &b[i][j]); 19 for (int i = 1; i <= n; ++i) 20 for (int j = 1; j <= m; ++j) 21 for (int k = 1; k <= p; ++k) 22 ans[i][j] += a[i][k] * b[k][j]; 23 int res = 0; 24 for (int i = 1; i <= n; ++i) 25 for (int j = 1; j <= m; ++j) 26 res ^= ans[i][j]; 27 printf("%d ", res); 28 } 29 } 30 31 int main() 32 { 33 #ifdef LOCAL 34 freopen("Test.in", "r", stdin); 35 #endif 36 37 Run(); 38 return 0; 39 }
2°
考虑到p很小,可以将它分块,比如说分成8Bit一块,那么对应的只有256种情况,可以预处理一下,然后乘法变成取值
复杂度大概在(4096 * 4096 * 8) 左右
1 #include <bits/stdc++.h> 2 using namespace std; 3 4 #define N 5000 5 6 int n, p, m; 7 int a[N][100], b[100][N], ap[N][10][256], bp[10][N], ans[N][N]; 8 9 void Run() 10 { 11 while (scanf("%d%d%d", &n, &p, &m) != EOF) 12 { 13 for (int i = 0; i < n; ++i) 14 for (int j = 0; j < p; ++j) 15 scanf("%X", &a[i][j]); 16 for (int j = 0; j < m; ++j) 17 for (int i = 0; i < p; ++i) 18 scanf("%1d", &b[i][j]); 19 p = (p - 1) / 8 + 1; 20 for (int i = 0; i < n; ++i) 21 for (int j = 0; j < p; ++j) 22 for (int k = 0; k < 256; ++k) 23 for (int l = 0; l < 8; ++l) 24 if (k & (1 << l)) ap[i][j][k] += a[i][j * 8 + l]; 25 for (int j = 0; j < m; ++j) 26 for (int i = p - 1; i >= 0; --i) 27 for (int k = 7; k >= 0; --k) 28 bp[i][j] = bp[i][j] * 2 + b[k + 8 * i][j]; 29 for (int i = 0; i < n; ++i) 30 for (int j = 0; j < m; ++j) 31 for (int k = 0; k < p; ++k) 32 ans[i][j] += ap[i][k][bp[k][j]]; 33 int res = 0; 34 for (int i = 0; i < n; ++i) 35 for (int j = 0; j < m; ++j) 36 res ^= ans[i][j]; 37 printf("%d ", res); 38 } 39 } 40 41 int main() 42 { 43 #ifdef LOCAL 44 freopen("Test.in", "r", stdin); 45 #endif 46 47 Run(); 48 return 0; 49 }