代码
1.暴力7/15:
#include <bits/stdc++.h> using namespace std; typedef long long ll; const int N = 5e6 + 10; int n, m; char mp[1005][1005]; int main() { cin >> n >> m; for (int i = 1; i <= n; i++) { for (int j = 1; j <= m; j++) { cin >> mp[i][j]; } } int ans = 0; for (int i = 1; i <= n; i++) // 暴力枚举 { for (int j = 1; j <= m; j++) { if (mp[i][j] == 'G') // 找到左上角是G的点 { for (int k = i; k <= n; k++) { for (int l = j; l <= m; l++) { int flag = 1; // flag是标记是否有R for (int x = i; x <= k; x++) // i k j l是矩形的左上,右上,左下,右下 { for (int y = j; y <= l; y++) { if (mp[x][y] == 'R') { flag = 0; break; } } if (flag == 0) { break; } } if (flag == 1) { ans = max(ans, (k - i + 1) * (l - j + 1)); } } } } } } cout << ans * 10; }
2.单调栈15/15
矩阵可以根据不同的行看成直方图:
(图源b站up主:轩哥码题)
#include <bits/stdc++.h> using namespace std; typedef long long ll; const int N = 1e3 + 10; int n, m, a[N][N], ans; char ch; // 单调栈,找右边第一个比自己小的数 // 栈顶元素>=要进来的元素:栈顶元素出栈 // 如果有元素出栈,则右边界为要进来的元素位置,左边界为栈中上一个元素位置 // 将二维平面看成不同的一维数组,对每一行进行单调栈操作 int maxRec(int x) { // 使用单调栈求某行作为x轴的最大矩形面积 int ret = 0; stack<int> s; s.push(0); for (int i = 1; i <= m + 1; i++) // i:位置 { while (a[x][i] < a[x][s.top()]) // 如果有元素出栈 { int h = a[x][s.top()]; s.pop(); int w = i - s.top() - 1; // 宽度 ret = max(ret, w * h); } s.push(i); } return ret; } int main() { cin >> n >> m; for (int i = 1; i <= n; i++) { for (int j = 1; j <= m; j++) { cin >> ch; if (ch == 'G') a[i][j] = 1; } } for (int i = 1; i <= n; i++) { for (int j = 1; j <= m; j++) { if (a[i][j])//a[i][j]是G,才算有效 a[i][j] += a[i - 1][j]; } } for (int i = 1; i <= n; i++) { ans = max(ans, maxRec(i)); } cout << ans * 10; return 0; }
3.动态规划15/15
#include <bits/stdc++.h> using namespace std; typedef long long ll; #define INF 0x3f3f3f3f int n, m; char aij; ll sum[1005][1005], ans, temp; // 动态规划,将二维转为一维 // 思路:R点设为负无穷大,二维用前缀和转移成一维,求一维的最大连续子序列 int main() { cin >> n >> m; for (int i = 1; i <= n; i++) { for (int j = 1; j <= m; j++) { cin >> aij; if (aij == 'R') temp = -INF; else temp = 10; sum[i][j] = sum[i - 1][j] + temp; } } for (int i = 1; i <= n; i++) { for (int j = i; j <= n; j++) { ll sum1 = 0; for (int k = 1; k <= m; k++) { sum1 += sum[j][k] - sum[i - 1][k]; if (sum1 < 0) { sum1 = 0; } ans = max(ans, sum1); } } } cout << ans; }