CQUOJ 2757 - Largest Submatrix
Now here is a matrix with letter 'a','b','c','w','x','y','z' and you can change 'w' to 'a' or 'b', change 'x' to 'b' or 'c', change 'y' to 'a' or 'c', and change 'z' to 'a', 'b' or 'c'. After you changed it, what's the largest submatrix with the same letters you can make?
Input
The input contains multiple test cases. Each test case begins with m and n (1 ≤ m, n ≤ 1000) on line. Then come the elements of a matrix in row-major order on m lines each with n letters. The input ends once EOF is met.
Output
For each test case, output one line containing the number of elements of the largest submatrix of all same letters.
Sample Input
2 4 abcw wxyz
Sample Output
3
题目大意:有个字母矩阵,包含字母"a、b、c、w、x、y、z",
其中,w能变为"a、b",x能变为"b、c",y能变为"a、c",z能变为"a、b、c"。
问能构成的最大字母完全一样的子矩阵面积为多大?
思路:和CQUOJ 1481一样的思路, 其中a[i][j]表示转换为字母a后以第i行为底,第j列上方连续空闲位置的高度。
b[i][j]表示字母b……,c[i][j]表示字母c……
遍历计算出该点向左右两边延伸的左右边界,从而计算出面积,最终比较计算出最大面积。
# include <iostream> # include <algorithm> # include <cstdio> # include <cstring> # include <queue> # include <vector> # include <cmath> # include <map> # include <set> # define pi acos(-1) # define LL long long # define INF 0x3f3f3f3f using namespace std; const int N = 1005; int a[N][N], b[N][N], c[N][N]; int L[N], R[N]; int main(void) { char ch; int n, m, i, j, sum, tmp; while (~scanf("%d %d", &n, &m)){ memset(a, 0, sizeof(a)); memset(b, 0, sizeof(b)); memset(c, 0, sizeof(c)); for (i = 1; i <= n; i++){ getchar(); for (j = 1; j <= m; j++){ scanf("%c", &ch); if (ch=='a' || ch=='w' || ch=='y' || ch=='z') a[i][j] = a[i-1][j] + 1; else a[i][j] = 0; if (ch=='b' || ch=='w' || ch=='x' || ch=='z') b[i][j] = b[i-1][j] + 1; else b[i][j] = 0; if (ch=='c' || ch=='x' || ch=='y' || ch=='z') c[i][j] = c[i-1][j] + 1; else c[i][j] = 0; } } sum = -1; // 计算 a[][] for (i = 1; i <= n; i++){ for (j = 1; j <= m; j++) L[j] = R[j] = j; a[i][0] = a[i][m+1] = -1; for (j = 2; j <= m; j++){ while (a[i][j] <= a[i][L[j]-1]) L[j] = L[L[j]-1]; } for (j = m-1; j >= 1; j--){ while (a[i][j] <= a[i][R[j]+1]) R[j] = R[R[j]+1]; } for (j = 1; j <= m; j++){ tmp = (R[j] - L[j] + 1) * a[i][j]; sum = max(sum, tmp); } } // 计算 b[][] for (i = 1; i <= n; i++){ for (j = 1; j <= m; j++) L[j] = R[j] = j; b[i][0] = b[i][m+1] = -1; for (j = 2; j <= m; j++){ while (b[i][j] <= b[i][L[j]-1]) L[j] = L[L[j]-1]; } for (j = m-1; j >= 1; j--){ while (b[i][j] <= b[i][R[j]+1]) R[j] = R[R[j]+1]; } for (j = 1; j <= m; j++){ tmp = (R[j] - L[j] + 1) * b[i][j]; sum = max(sum, tmp); } } // 计算 c[][] for (i = 1; i <= n; i++){ for (j = 1; j <= m; j++) L[j] = R[j] = j; c[i][0] = c[i][m+1] = -1; for (j = 2; j <= m; j++){ while (c[i][j] <= c[i][L[j]-1]) L[j] = L[L[j]-1]; } for (j = m-1; j >= 1; j--){ while (c[i][j] <= c[i][R[j]+1]) R[j] = R[R[j]+1]; } for (j = 1; j <= m; j++){ tmp = (R[j] - L[j] + 1) * c[i][j]; sum = max(sum, tmp); } } cout<<sum<<endl; } return 0; }

浙公网安备 33010602011771号