SenseTime Ace Coder Challenge 暨 商汤在线编程挑战赛*
预处理四个角,枚举重叠段,发现可以前缀max
1 #include <bits/stdc++.h> 2 using namespace std; 3 const int INF = 1e9; 4 int G[1111][1111], lu[1111][1111], ru[1111][1111], ld[1111][1111], rd[1111][1111]; 5 6 int main(){ 7 int T; 8 scanf("%d", &T); 9 for(int kase = 1; kase <= T; kase++){ 10 int n, m; 11 scanf("%d %d", &n, &m); 12 for(int i = 1; i <= n; ++i) 13 for(int j = 1; j <= m; ++j) 14 scanf("%d", &G[i][j]); 15 // lu 16 lu[1][1] = G[1][1]; 17 for(int i = 1; i <= n; ++i){ 18 for(int j = 1; j <= m; ++j){ 19 if(i == 1 && j == 1) continue; 20 if(i == 1) lu[i][j] = lu[i][j-1] + G[i][j]; 21 else if(j == 1) lu[i][j] = lu[i-1][j] + G[i][j]; 22 else lu[i][j] = max(lu[i-1][j], lu[i][j-1]) + G[i][j]; 23 } 24 } 25 // ru 26 ru[1][m] = G[1][m]; 27 for(int i = 1; i <= n; ++i){ 28 for(int j = m; j >= 1; --j){ 29 if(i == 1 && j == m) continue; 30 if(i == 1) ru[i][j] = ru[i][j+1] + G[i][j]; 31 else if(j == m) ru[i][j] = ru[i-1][j] + G[i][j]; 32 else ru[i][j] = max(ru[i-1][j], ru[i][j+1]) + G[i][j]; 33 } 34 } 35 // ld 36 ld[n][1] = G[n][1]; 37 for(int i = n; i >= 1; --i){ 38 for(int j = 1; j <= m; ++j){ 39 if(i == n && j == 1) continue; 40 if(i == n) ld[i][j] = ld[i][j-1] + G[i][j]; 41 else if(j == 1) ld[i][j] = ld[i+1][j] + G[i][j]; 42 else ld[i][j] = max(ld[i+1][j], ld[i][j-1]) + G[i][j]; 43 } 44 } 45 // rd 46 rd[n][m] = G[n][m]; 47 for(int i = n; i >= 1; --i){ 48 for(int j = m; j >= 1; --j){ 49 if(i == n && j == m) continue; 50 if(i == n) rd[i][j] = rd[i][j+1] + G[i][j]; 51 else if(j == m) rd[i][j] = rd[i+1][j] + G[i][j]; 52 else rd[i][j] = max(rd[i+1][j], rd[i][j+1]) + G[i][j]; 53 } 54 } 55 56 int ans = -INF; 57 for(int i = 1; i <= n; ++i){ 58 int sum = 0, M = -INF; 59 for(int j = 1; j <= m; ++j){ 60 int t1, t2; 61 if(i == 1 && j == 1) t1 = ld[i+1][j]; 62 else if(i == n && j == 1) t1 = lu[i-1][j]; 63 else if(i == 1) t1 = lu[i][j-1] + ld[i+1][j]; 64 else if(i == n) t1 = lu[i-1][j] + ld[i][j-1]; 65 else if(j == 1) t1 = lu[i-1][j] + ld[i+1][j]; 66 else t1 = max(lu[i-1][j] + ld[i+1][j], max(lu[i-1][j] + ld[i][j-1], lu[i][j-1] + ld[i+1][j])); 67 if(i == 1 && j == m) t2 = rd[i+1][j]; 68 else if(i == n && j == m) t2 = ru[i-1][j]; 69 else if(i == 1) t2 = ru[i][j+1] + rd[i+1][j]; 70 else if(i == n) t2 = ru[i-1][j] + rd[i][j+1]; 71 else if(j == m) t2 = ru[i-1][j] + rd[i+1][j]; 72 else t2 = max(ru[i-1][j] + rd[i+1][j], max(ru[i-1][j] + rd[i][j+1], ru[i][j+1] + rd[i+1][j])); 73 ans = max(ans, sum + G[i][j] + t2 + M); 74 M = max(M, t1 - sum); 75 sum += G[i][j]; 76 } 77 } 78 for(int j = 1; j <= m; ++j){ 79 int sum = 0, M = -INF; 80 for(int i = 1; i <= n; ++i){ 81 int t1, t2; 82 if(i == 1 && j == 1) t1 = ru[i][j+1]; 83 else if(i == 1 && j == m) t1 = lu[i][j-1]; 84 else if(j == 1) t1 = lu[i-1][j] + ru[i][j+1]; 85 else if(j == m) t1 = lu[i][j-1] + ru[i-1][j]; 86 else if(i == 1) t1 = lu[i][j-1] + ru[i][j+1]; 87 else t1 = max(lu[i][j-1] + ru[i][j+1], max(lu[i][j-1] + ru[i-1][j], lu[i-1][j] + ru[i][j+1])); 88 if(i == n && j == 1) t2 = rd[i][j+1]; 89 else if(i == n && j == m) t2 = ld[i][j-1]; 90 else if(j == 1) t2 = ld[i+1][j] + rd[i][j+1]; 91 else if(j == m) t2 = ld[i][j-1] + rd[i+1][j]; 92 else if(i == n) t2 = ld[i][j-1] + rd[i][j+1]; 93 else t2 = max(ld[i][j-1] + rd[i][j+1], max(ld[i][j-1] + rd[i+1][j], ld[i+1][j] + rd[i][j+1])); 94 ans = max(ans, sum + G[i][j] + t2 + M); 95 M = max(M, t1 - sum); 96 sum += G[i][j]; 97 } 98 } 99 for(int i = 2; i < n; i++) 100 for(int j = 2; j < m; ++j) 101 ans = max(ans, G[i][j] + max(lu[i-1][j] + rd[i+1][j] + ru[i][j+1] + ld[i][j-1], lu[i][j-1] + rd[i][j+1] + ru[i-1][j] + ld[i+1][j])); 102 printf("Case #%d: %d ", kase, ans); 103 } 104 return 0; 105 }
我bitset过不了冷静分析了一个n3做法
1 #include <bits/stdc++.h> 2 using namespace std; 3 int G1[222][222], G2[222][222]; 4 5 int main(){ 6 int T; 7 scanf("%d", &T); 8 for(int kase = 1; kase <= T; ++kase){ 9 int N; 10 scanf("%d", &N); 11 for(int i = 1; i <= N; ++i){ 12 char s[222]; 13 scanf("%s", s + 1); 14 for(int j = 1; j <= N; ++j) 15 G1[i][j] = (s[j] == '1' ? 1 : 0), G2[i][j] = 0; 16 } 17 for(int i = 1; i <= N; ++i){ 18 for(int j = 1; j <= N; ++j){ 19 if(!G1[i][j]) continue; 20 for(int k = 1; k <= N; ++k) G2[i][k] += G1[j][k]; 21 } 22 } 23 int ans = 0; 24 for(int i = 1; i <= N; ++i){ 25 for(int k = 1; k <= N; ++k){ 26 if(i == k) continue; 27 int c = 0; 28 for(int p = 1; p <= N; ++p){ 29 if(p == i || p == k) continue; 30 if(G2[i][p] && G1[k][p]) c++; 31 } 32 for(int j = 1; j <= N; ++j){ 33 if(j == i || j == k) continue; 34 if(!G1[i][j] || !G1[k][j]) continue; 35 int b = G2[i][j] && G1[k][j] ? 1 : 0; 36 ans += c - b; 37 } 38 } 39 } 40 for(int j = 1; j <= N; ++j){ 41 for(int p = 1; p <= N; ++p){ 42 if(!G1[j][p]) continue; 43 int c = 0; 44 for(int k = 1; k <= N; ++k) c += G1[j][k] && G1[p][k] ? 1 : 0; 45 for(int i = 1; i <= N; ++i){ 46 if(i == j || i == p) continue; 47 if(!G1[i][j]) continue; 48 if(G2[i][p] != 1) continue; 49 int b = G1[j][i] && G1[p][i] ? 1 : 0; 50 ans -= c - b + c - b; 51 } 52 } 53 } 54 for(int i = 1; i <= N; ++i){ 55 for(int p = 1; p <= N; ++p){ 56 if(i == p) continue; 57 if(G2[i][p] != 2) continue; 58 vector<int> v; 59 for(int k = 1; k <= N; ++k) 60 if(G1[i][k] && G1[p][k]) v.push_back(k); 61 if(G1[v[0]][v[1]]) ans -= 2; 62 } 63 } 64 printf("Case #%d: %s ", kase, ans > 0 ? "Starfish!" : "Walk Walk"); 65 } 66 return 0; 67 }