小记:这个算是1506,1505的再次升级版吧,1506是一维版本,1505是二维版本,这个2870则是可以变动两三次的二维版本。 1A!
思路:如1505一样,我们一行一行的处理, 因为w,x,y,z都可以变,但是a,b,c不能变,那么我们以a,b,c为基础,每个w,x,y,z都变a,或b或c。
即,我们对每一个点计算出它是a或者b或者c时所能得到的最大子矩
h[i][j] 表示当前行第i个字符是j 然后往上碰到第一个不同的字符的高度
l[i][j] 表示当前行第i个字符是j的时候,其左边连续到它这个位置高度大于等于它自己的高度的最长长度
r[i][j] 表示当前行第i个字符是j的时候,其右边连续到它这个位置高度大于等于它自己的高度的最长长度
因为a,b,c不变,所以j 的值只有3个,我们对每个点处理下三个值所能得到的最大值,保存最大的那个就是结果了
if( 当前字符== j ) h[i][j] ++, 其它字符都归0
l[i][j] = l[l[i][j] - 1][j] (l[i][j] > 0 && h[l[i][j] - 1] >= h[i][j]) (j = 1(a),2( b),3 (c))
r[i][j] = r[l[i][j] - 1][j] (r[i][j] +1 > m && h[r[i][j] - 1] >= h[i][j]) (j = 1(a), 2(b), 3(c))
初始化 记得 l[i][j] = -1, r[i][j] = m,然后碰到j的时候 就左右都赋值为 i, 高度初始化都为0
code:
#include <iostream> #include <stdio.h> #include <string.h> #include <math.h> #include <stdlib.h> #include <map> #include <set> #include <vector> #include <stack> #include <queue> #include <algorithm> using namespace std; #define mst(a,b) memset(a,b,sizeof(a)) #define REP(a,b,c) for(int a = b; a < c; ++a) #define eps 10e-8 const int MAX_ = 1010; const int N = 100010; const int INF = 0x7fffffff; int h[MAX_][3]; int l[MAX_][3], r[MAX_][3]; char str[MAX_][MAX_]; int main(){ int n, m, ans; while(~scanf("%d%d", &n, &m)){ REP(i, 0, m){ REP(ii, 0, 3){ l[i][ii] = -1; r[i][ii] = m; h[i][ii] = 0; } } ans = -1; REP(j, 0, n){ scanf("%s", str[j]); REP(i, 0, m){ switch(str[j][i]){ case 'a': l[i][0] = i; r[i][0] = i; h[i][0]++; h[i][1] = 0; h[i][2] = 0; break; case 'b': l[i][1] = i; r[i][1] = i; h[i][0] = 0; h[i][1] ++; h[i][2] = 0; break; case 'c': l[i][2] = i; r[i][2] = i; h[i][0] = 0; h[i][1] = 0; h[i][2] ++; break; case 'w': l[i][0] = i; r[i][0] = i; l[i][1] = i; r[i][1] = i; h[i][0]++; h[i][1] ++; h[i][2] = 0; break; case 'x': l[i][1] = i; r[i][1] = i; l[i][2] = i; r[i][2] = i; h[i][0] = 0; h[i][1] ++; h[i][2] ++; break; case 'y': l[i][2] = i; r[i][2] = i; l[i][0] = i; r[i][0] = i; h[i][0]++; h[i][1] = 0; h[i][2] ++; break; case 'z': l[i][0] = i; r[i][0] = i; l[i][1] = i; r[i][1] = i; l[i][2] = i; r[i][2] = i; h[i][0] ++; h[i][1] ++; h[i][2] ++; break; } } REP(ii, 0, 3){ REP(k, 0, m){ while(l[k][ii] > 0 && h[l[k][ii] - 1][ii] >= h[k][ii]){ l[k][ii] = l[l[k][ii] - 1][ii]; } } } REP(ii, 0, 3){ for(int k = m-1; k > -1; --k){ while(r[k][ii] + 1 < m && h[r[k][ii] + 1][ii] >= h[k][ii]){ r[k][ii] = r[r[k][ii] + 1][ii]; } } } REP(ii, 0, 3){ REP(k, 0, m){ if(l[k][ii] < 0 || r[k][ii] > m-1)continue; int tmp = (r[k][ii] - l[k][ii] + 1) * h[k][ii]; //printf(" | (%d %d) = %d | ", l[k][ii], r[k][ii], tmp); ans = max(ans, tmp); } } //printf("\n"); } printf("%d\n", ans); } return 0; }