[arc081] F - Flip and Rectangles——思维题+单调栈

题目大意:

给定一个\(n\times m\)的01矩形,每次可以翻转一行或者翻转一列。
求翻转若干次之后的最大全1子矩形。

思路:

首先我们要知道一个结论:如果一个子矩形可以被翻转成为全1矩形,那么它内部的每一个\(2\times 2\)的子矩形的1的个数为偶数。
如果存在一个\(2\times 2\)的子矩形有奇数个1,那么无论怎么操作都还是奇数。
如果所有的\(2\times 2\)的子矩形都有偶数个1,我们可以先使这个矩形的第一行第一列都变为1,根据奇偶性不难发现整个矩阵此时必定全部都变成了1。
于是我们只需要找到一个最大的只包含偶数1的矩形就好了,这可以转化为经典的最大全1子矩阵问题,用单调栈维护可以做到\(O(n^2)\)。
注意到答案最小为\(\max(n,m)\),最后记得再chkmax一下。

#include<bits/stdc++.h>

#define REP(i,a,b) for(int i=a,i##_end_=b;i<=i##_end_;++i)
#define DREP(i,a,b) for(int i=a,i##_end_=b;i>=i##_end_;--i)
#define MREP(i,x) for(int i=beg[x],v;v=to[i],i;i=las[i])
#define debug(x) cout<<#x<<"="<<x<<endl
#define fi first
#define se second
#define mk make_pair
#define pb push_back
#define y1 asdasd
typedef long long ll;

using namespace std;

void File(){
    freopen("speech.in","r",stdin);
    freopen("speech.out","w",stdout);
}

template<typename T>void read(T &_){
    T __=0,mul=1; char ch=getchar();
    while(!isdigit(ch)){
        if(ch=='-')mul=-1;
        ch=getchar();
    }
    while(isdigit(ch))__=(__<<1)+(__<<3)+(ch^'0'),ch=getchar();
    _=__*mul;
}

const int maxn=2000+10;
int n,m,a[maxn][maxn],b[maxn][maxn],ans;
char s[maxn];
stack<int>stk;

int main(){
    File();
    read(n); read(m);
    if(n==1 || m==1)return printf("%d\n",n*m),0;
    REP(i,1,n){
        scanf("%s",s+1);
        REP(j,1,m)a[i][j]=(s[j]=='#');
    }
    REP(i,1,n-1)REP(j,1,m-1){
        int c[2]={0};
        ++c[a[i][j]];
        ++c[a[i+1][j]];
        ++c[a[i][j+1]];
        ++c[a[i+1][j+1]];
        b[i][j]=!(c[1]%2);
        if(b[i][j])b[i][j]+=b[i-1][j];
    }
    REP(i,1,n-1){
        int las;
        REP(j,1,m-1){
            las=j;
            while(!stk.empty() && b[i][stk.top()]>=b[i][j]){
                las=stk.top(); stk.pop();
                if(b[i][las])ans=max(ans,(j-las+1)*(b[i][las]+1));
            }
            b[i][las]=b[i][j];
            stk.push(las);
        }
        while(!stk.empty()){
            las=stk.top(); stk.pop();
            if(b[i][las])ans=max(ans,(m-las+1)*(b[i][las]+1));
        }
    }
    printf("%d\n",max(ans,max(n,m)));
    return 0;
}

原文地址:https://www.cnblogs.com/ylsoi/p/9917837.html

时间: 2024-10-09 22:11:29

[arc081] F - Flip and Rectangles——思维题+单调栈的相关文章

猴子向右看,FOJ上某题 单调栈

N (1 <= N <= 100,000) monkeys in the mountains, conveniently numbered 1..N, are once again standing in a row. Monkey i has height Hi (1 <= Hi <= 1,000,000). Each monkey is looking to his left toward those with higher index numbers. We say that

POJ-2559 Largest Rectangle in a Histogram(单调栈)

Largest Rectangle in a Histogram Time Limit: 1000MS   Memory Limit: 65536K Total Submissions: 22171   Accepted: 7173 Description A histogram is a polygon composed of a sequence of rectangles aligned at a common base line. The rectangles have equal wi

poj 3250 Bad Hair Day (单调栈)

Bad Hair Day Time Limit: 2000MS   Memory Limit: 65536K Total Submissions: 14883   Accepted: 4940 Description Some of Farmer John's N cows (1 ≤ N ≤ 80,000) are having a bad hair day! Since each cow is self-conscious about her messy hairstyle, FJ wants

[Agc081F/At2699] Flip and Rectangles - 单调栈,结论

[Agc081F/At2699] 给出一个拥有 \(H\times W\) 个格子的棋盘,每个格子的颜色为黑色或白色. Snuke 可以进行任意次下列操作: 选择棋盘中的一行或一列,将这一行或一列的颜色翻转(黑变成白,白变成黑) Snuke 想知道,在他进行操作后,棋盘中最大的全黑矩形最大能为多少. 考虑 \(2\times 2\) 方格,当且仅当偶数个黑时,可以做成全黑 大矩形能做成全黑,当且仅当所有 \(2\times 2\) 子格都是偶数个黑 然后就是一个很朴素的单调栈求最大矩形了 注意到

Unique Encryption Keys (思维题 预处理)

题目 题意:给m个数字, q次询问, 询问b到e之间如果有重复数字就输出, 没有就输出OK 思路:用f[i]数组 记录从i开始向后最近的有重复数字的 位置, 如 1 3 2 2, 则f[1] = 4; 如果离a最近的重复数字的位置 都大于b, 就说明没有重复数字. f[]数组需要预处理,从后向前. 1 #include <iostream> 2 #include <cstdio> 3 #include <cstring> 4 #include <vector>

hdu 4972 A simple dynamic programming problem (转化 乱搞 思维题) 2014多校10

题目链接 题意:给定一个数组记录两队之间分差,只记分差,不记谁高谁低,问最终有多少种比分的可能性 分析: 类似cf的题目,比赛的时候都没想出来,简直笨到极点..... 1 #include <iostream> 2 #include <cstdio> 3 #include <cstring> 4 #include <cstdlib> 5 #include <cmath> 6 #include <vector> 7 #include &

HDU 4923 Room and Moor (多校第六场C题) 单调栈

Problem Description PM Room defines a sequence A = {A1, A2,..., AN}, each of which is either 0 or 1. In order to beat him, programmer Moor has to construct another sequence B = {B1, B2,... , BN} of the same length, which satisfies that: Input The inp

hdu 4923 Room and Moor (单调栈+思维)

题意: 给一个0和1组成的序列a,要构造一个同样长度的序列b.b要满足非严格单调,且 值为0到1的实数.最后使得  sum((ai-bi)^2)最小. 算法: 首先a序列开始的连续0和末尾的连续1是可以不考虑的.因为只要b序列对应开头为0. 末尾为1,既不影响单调性又能使对应的(ai-bi)^2=0. 然后, 先找111100.11100.10这样以1开始以0结束的序列块.每一块对应的b值相等且均为 这一块的平均值,即1的个数/0和1的总个数. 但是要满足b的单调性,则我们用栈来维护,如果后面一

智商的比拼——思维题思考指南

智商的比拼--思维题思考指南 最近做了几道思维题,感觉思维题就是烧脑,而且费劲,而且做不出QAQ!! 思维题可能分一下几个类别吧 鲨壁结论题.神犇之于结论题,如鱼之于水.而我之于结论题,QAQ. 数论大法好.有些题目直接数学建模找结论啊QAQ,就比如[Running]这道题,关键性的东西就是\((a_i,n)|\ l\),实际上这个就是数学建立同余方程然后得出来的一个浅显结论(我找这个"浅显"的结论花了\(30min\) \(QAQ\)). 代数大法好.实际上和前面那个重合了,不过拿出