怎么分析这道题呢?
首先 ,我们注意到一点:
不管怎么操作,任意一个2*2方格中的 "#"个数的奇偶性是不变的。
所以,如果一个2*2方格中有奇数个"#",这个方格里的格子永远不可能变成同一种颜色。
并且,如果一个矩形中,所有2*2方格中有偶数个"#",那么它一定可以能变成只有一种颜色的矩形。
为什么?
先把这个矩形的第一行和第一列都变成同一种颜色,这个操作任何矩形都能做到。
如果这个矩形中,所有2*2方格中有偶数个"#",那么在左上角的2*2方格一定都是"#"。(一直是偶数个“#”)。这样在它右边的2*2方格同样一定都是"#"。以此类推,它一定可以能变成只有一种颜色的矩形。
然后我们再来维护最大的不包含有奇数个"#"的2*2方格的矩形。
这是一个经典问题,我们可以用单调栈来解决。
#include<bits/stdc++.h>
using namespace std;
const int maxn=2005;
int h, w, len[maxn], up[maxn], down[maxn], nxt[maxn], ans;
char s[maxn][maxn];
int bad(int y, int x){
int ans = (s[y][x] == '#')^
(s[y][x+1] == '#')^
(s[y+1][x] == '#')^
(s[y+1][x+1] == '#');
return ans;
}
void solve(){
stack<int> stk;
for(int i=1;i<=h;i++){
while(!stk.empty() && len[stk.top()] >= len[i])
stk.pop();
if(stk.empty())up[i]=0;
else up[i]=stk.top();
if(len[i] != 0)stk.push(i);
}
while(!stk.empty()) stk.pop();
for(int i=h;i>=1;i--){
while(!stk.empty() && len[stk.top()] >= len[i])
stk.pop();
if(stk.empty())down[i]=h;
else down[i]=stk.top();
if(len[i] != 0)stk.push(i);
}
for(int i=1;i<=h;i++){
ans = max(ans, len[i]*(down[i]-up[i]));
// printf("%d:%d %d %d
",i,len[i],down[i],up[i]);
}
}
int main()
{
scanf("%d%d",&h,&w);
for(int i = 1; i <= h; i++)
scanf("%s", s[i]+1);
for(int i = 1; i <= w; i++){
for(int j = 1; j <= h; j++){
if(nxt[j]) len[j] = 1;
else len[j]++;
if(bad(j,i) && i!=w && j!=h) nxt[j] = 1;
else nxt[j] = 0;
// printf("%d
",nxt[j]);
}
// printf("
");
solve();
}
printf("%d
", ans);
return 0;
}