题目描述
国际象棋是世界上最古老的博弈游戏之一,和中国的围棋、象棋以及日本的将棋同享盛名。据说国际象棋起源于易经的思想,棋盘是一个8×88 \times 88×8大小的黑白相间的方阵,对应八八六十四卦,黑白对应阴阳。
而我们的主人公小Q
,正是国际象棋的狂热爱好者。作为一个顶尖高手,他已不满足于普通的棋盘与规则,于是他跟他的好朋友小W
决定将棋盘扩大以适应他们的新规则。
小Q
找到了一张由N×MN \times MN×M个正方形的格子组成的矩形纸片,每个格子被涂有黑白两种颜色之一。小Q
想在这种纸中裁减一部分作为新棋盘,当然,他希望这个棋盘尽可能的大。
不过小Q
还没有决定是找一个正方形的棋盘还是一个矩形的棋盘(当然,不管哪种,棋盘必须都黑白相间,即相邻的格子不同色),所以他希望可以找到最大的正方形棋盘面积和最大的矩形棋盘面积,从而决定哪个更好一些。
于是小Q
找到了即将参加全国信息学竞赛的你,你能帮助他么?
输入输出格式
输入格式:包含两个整数NNN和MMM,分别表示矩形纸片的长和宽。接下来的NNN行包含一个N ×MN \ \times MN ×M的010101矩阵,表示这张矩形纸片的颜色(000表示白色,111表示黑色)。
输出格式:包含两行,每行包含一个整数。第一行为可以找到的最大正方形棋盘的面积,第二行为可以找到的最大矩形棋盘的面积(注意正方形和矩形是可以相交或者包含的)。
输入输出样例
说明
对于20%20\%20%的数据,N,M≤80N, M ≤ 80N,M≤80
对于40%40\%40%的数据,N,M≤400N, M ≤ 400N,M≤400
对于100%100\%100%的数据,N,M≤2000N, M ≤ 2000N,M≤2000
题解
某天中午去吃超好吃的鱼粉,路上,一位选手问我们,
你知道悬线法是什么吗?!
我不知道,于是我问他是干嘛的,于是他洋洋洒洒的摆出了这道题。
我kiao,这不就是我校传了好几届的最大矩阵题吗?!
然后我把那道题改造了一下,成功AC。
————————————
跟原题不同的是,我们传承前缀和时的条件改为此位和上一位不同。
并且和左右接通时,判断是否不同。如果相同就不连。
1 /* 2 qwerta 3 P1169 [ZJOI2007]棋盘制作 4 Accepted 5 100 6 代码 C++,1.5KB 7 提交时间 2018-10-14 21:34:02 8 耗时/内存 9 29ms, 688KB 10 */ 11 // luogu-judger-enable-o2 12 #include<iostream> 13 #include<cstdio> 14 #include<queue> 15 #include<cmath> 16 using namespace std; 17 #define R register 18 int s[2003]; 19 int a[2003]; 20 struct emm{ 21 int nod,v; 22 }; 23 struct cmp{ 24 bool operator()(emm qaq,emm qwq){ 25 return qaq.v<qwq.v; 26 } 27 }; 28 priority_queue<emm,vector<emm>,cmp>q; 29 int siz[2003],fa[2003]; 30 bool sf[2003]; 31 int fifa(int x) 32 { 33 if(fa[x]==x)return x; 34 return fa[x]=fifa(fa[x]); 35 } 36 inline void con(int x,int y) 37 { 38 int u=fifa(x),v=fifa(y); 39 siz[u]+=siz[v]; 40 fa[v]=u; 41 return; 42 } 43 inline int read() 44 { 45 char ch=getchar(); 46 int x=0; 47 while(!isdigit(ch))ch=getchar(); 48 if(isdigit(ch)){if(ch=='1')x=1;ch=getchar();} 49 return x; 50 } 51 int main() 52 { 53 //freopen("a.in","r",stdin); 54 int n,m; 55 scanf("%d%d",&n,&m); 56 int ansz=0,ansc=0; 57 for(R int i=1;i<=n;++i) 58 { 59 for(R int i=1;i<=m;++i) 60 { 61 int x=read(); 62 if(a[i]+x==1)s[i]++; 63 else s[i]=1; 64 a[i]=x; 65 q.push((emm){i,s[i]}); 66 } 67 for(R int i=1;i<=m;++i) 68 fa[i]=i,siz[i]=1,sf[i]=0; 69 a[0]=a[m+1]=2; 70 while(!q.empty()) 71 { 72 int i=q.top().nod,x=q.top().v;q.pop(); 73 sf[i]=1; 74 if(a[i-1]+a[i]==1&&sf[i-1]) 75 con(i-1,i); 76 if(a[i]+a[i+1]==1&&sf[i+1]) 77 con(i,i+1); 78 int fi=fifa(i),mi=min(siz[fi],x); 79 ansz=max(ansz,mi*mi); 80 ansc=max(ansc,siz[fi]*x); 81 } 82 } 83 printf("%d\n%d",ansz,ansc); 84 return 0; 85 }