1. 程式人生 > >[arc081F]Flip and Rectangles-[黑白染色]

[arc081F]Flip and Rectangles-[黑白染色]

color str and 改變 des tdi cout rip 個數

Description

傳送門

Solution

有一個神秘的結論。。我不知道大佬是怎麽場上推出來的。

一個黑白染色圖,每次可以任意翻轉行或列的顏色,如果每個2*2的子矩陣內黑色格子都是偶數個,則可以把它變成全黑,反之則一定不行。

證明“一定不行”:翻轉行或列的時候不會改變任何2*2子矩陣的奇偶性,所以如果某個2*2矩陣內有奇數個黑色格子,那它就會一直有奇數個黑格子,無法變成全黑;

證明“可以”-變化方法:我們先把圖的第一行變成全黑,由於2*2子矩陣奇偶性不改變,所以圖的每一行裏所有格子顏色一定相等,否則一定會構造出一個有奇數個黑格子的2*2矩陣。

我們定義偶數個黑格子的2*2子矩陣是“滿足要求的”。

維護left[i][j]和right[i][j]。left[i][j]表示第i行由j向左最多有多少個滿足要求的矩陣;right就表示由j向右的連續滿足要求矩陣的個數。

666

Code

#include<iostream>
#include<cstdio>
#include<cstring>
#include<cmath>
using namespace std;
int h,w;
int a[2010][2010];
bool _is[2010][2010];
int l[2010][2010],r[2010][2010],up[2010][2010];
char ch[2010];
int ans; int main() { scanf("%d%d",&h,&w); for (int i=1;i<=h;i++) { scanf("%s",ch+1); for (int j=1;j<=w;j++) a[i][j]=ch[j]==#?1:0; } for (int i=1;i<h;i++) for (int j=1;j<w;j++) _is[i][j]=a[i][j]^a[i+1][j]^a[i+1][j+1]^a[i][j+1]; for
(int i=1;i<h;i++) { for (int j=1;j<w;j++) l[i][j]=_is[i][j]?0:l[i][j-1]+1; for (int j=w-1;j;j--) r[i][j]=_is[i][j]?0:r[i][j+1]+1; } for (int i=1;i<w;i++) l[0][i]=r[0][i]=1e9; ans=max(h,w); for (int i=1;i<h;i++) for (int j=1;j<w;j++) { if (_is[i][j]) up[i][j]=0,l[i][j]=r[i][j]=1e9; else { up[i][j]=up[i-1][j]+1; l[i][j]=min(l[i][j],l[i-1][j]); r[i][j]=min(r[i][j],r[i-1][j]); ans=max(ans,(up[i][j]+1)*(l[i][j]+r[i][j])); } } cout<<ans; }

[arc081F]Flip and Rectangles-[黑白染色]