• 翻转长方形 (不知名oj中一道个人私题)--单调栈维护最大子矩形


    怎么分析这道题呢?

    首先 ,我们注意到一点:
    不管怎么操作,任意一个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;	
    }

  • 相关阅读:
    【强转】QEMU+GDB调试linux内核全过程
    从上往下打印二叉树
    栈的压入、弹出序列
    包含main函数的栈
    顺时针打印矩阵
    Linux终端美化
    Linux 终端美化
    KDE桌面环境自带的Konsole终端配置
    KDE美化及常用设置
    KDE常用桌面插件总结
  • 原文地址:https://www.cnblogs.com/Eroad/p/9373475.html
Copyright © 2020-2023  润新知