A 矩陣乘法c++
思路:數組
1° 牛客機器太快了,暴力能過。ide
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\n", 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°spa
考慮到p很小,能夠將它分塊,好比說分紅8Bit一塊,那麼對應的只有256種狀況,能夠預處理一下,而後乘法變成取值3d
複雜度大概在(4096 * 4096 * 8) 左右code
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\n", 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 }
B 字符串的冪blog
留坑。排序
C 生命遊戲遊戲
留坑。字符串
D 數格點
留坑。
E 數據排序
留坑。
F 平衡二叉樹
思路:顯然,答案最大確定是根節點下左子樹是滿二叉樹,右子樹是最小平衡二叉樹
深度爲n的二叉平衡樹的最小節點數 = 左平衡樹的最小節點數 + 右平衡樹的最小結點樹 + 當前樹的根節點樹(1)
顯然 ,右平衡樹的高度能夠比左平衡樹少d
當$n <= d$ 的時候 $F[n] = max(n, 0)$
因此$F[n] = F[n - 1] + F[n - d - 1] +1$
滿二叉樹的結點個數是$2^n$
1 #include <bits/stdc++.h> 2 using namespace std; 3 using ll = long long; 4 5 int n, d; 6 ll f[100]; 7 8 ll qpow(ll base, ll n) 9 { 10 ll res = 1; 11 while (n) 12 { 13 if (n & 1) res *= base; 14 base *= base; 15 n >>= 1; 16 } 17 return res; 18 } 19 20 ll work(int h) 21 { 22 if (h <= d) 23 return max(h, 0); 24 if (f[h]) return f[h]; 25 f[h] = work(h - 1) + work(h - d - 1) + 1; 26 return f[h]; 27 } 28 29 void Run() 30 { 31 while (scanf("%d%d", &n, &d) != EOF) 32 { 33 memset(f, 0, sizeof f); 34 printf("%lld\n", qpow(2ll, n - 1) - work(n - d - 1) - 1); 35 } 36 } 37 38 int main() 39 { 40 #ifdef LOCAL 41 freopen("Test.in", "r", stdin); 42 #endif 43 44 Run(); 45 return 0; 46 }
G 數組合並
留坑。
H 卡牌遊戲
思路:考慮抽到一張卡片的機率是$\frac{m}{n}$ 那麼指望就是 $\frac{n}{m}$ 抽到一張以後再抽一張的機率是$\frac{m - 1}{n - 1}$
1 #include <bits/stdc++.h> 2 using namespace std; 3 4 int t, n, m, k; 5 6 int main() 7 { 8 scanf("%d", &t); 9 for (int kase = 1; kase <= t; ++kase) 10 { 11 scanf("%d%d%d", &n, &m, &k); 12 double res = 0; 13 for (int i = 1; i <= k; ++i, --n, --m) 14 res += n * 1.0 / m; 15 printf("Case #%d: %.10f\n", kase, res); 16 } 17 return 0; 18 }
I 遊戲
留坑。
J 魔法陣
留坑。
K 排隊
留坑。