1. 程式人生 > >[ZJOI2007]棋盤制作

[ZJOI2007]棋盤制作

易經 顏色 color 不同 愛好 接下來 bsp 白色 兩個

題目描述

國際象棋是世界上最古老的博弈遊戲之一,和中國的圍棋、象棋以及日本的將棋同享盛名。據說國際象棋起源於易經的思想,棋盤是一個8*8大小的黑白相間的方陣,對應八八六十四卦,黑白對應陰陽。

而我們的主人公小Q,正是國際象棋的狂熱愛好者。作為一個頂尖高手,他已不滿足於普通的棋盤與規則,於是他跟他的好朋友小W決定將棋盤擴大以適應他們的新規則。

小Q找到了一張由N*M個正方形的格子組成的矩形紙片,每個格子被塗有黑白兩種顏色之一。小Q想在這種紙中裁減一部分作為新棋盤,當然,他希望這個棋盤盡可能的大。

不過小Q還沒有決定是找一個正方形的棋盤還是一個矩形的棋盤(當然,不管哪種,棋盤必須都黑白相間,即相鄰的格子不同色),所以他希望可以找到最大的正方形棋盤面積和最大的矩形棋盤面積,從而決定哪個更好一些。

於是小Q找到了即將參加全國信息學競賽的你,你能幫助他麽?

輸入輸出格式

輸入格式:

包含兩個整數N和M,分別表示矩形紙片的長和寬。接下來的N行包含一個N * M的01矩陣,表示這張矩形紙片的顏色(0表示白色,1表示黑色)。

輸出格式:

包含兩行,每行包含一個整數。第一行為可以找到的最大正方形棋盤的面積,第二行為可以找到的最大矩形棋盤的面積(註意正方形和矩形是可以相交或者包含的)。

輸入輸出樣例

輸入樣例#1:
3 3
1 0 1
0 1 0
1 0 0
輸出樣例#1:
4
6

說明

對於20%的數據,N, M ≤ 80

對於40%的數據,N, M ≤ 400

對於100%的數據,N, M ≤ 2000

題解:

動態規劃

令L[i][j]表示左邊,R[i][j]表示右邊,H[i][j]表示上面

轉移如下,當a[i][j]!=a[i-1][j]時

L[i][j]=min(L[i][j],L[i-1][j]),R[i][j]=min(R[i][j],R[i-1][j])

H[i][j]=H[i-1][j]+1

顯然,正方形取min(H[i][j]+1,L[i][j]+R[i][j]-1)

矩形取(H[i][j]+1)*(L[i][j]+R[i][j]-1)

本來分析覺得不需要R數組,但是只有60分,加上R數組就AC不知道為什麽

 1 #include<iostream>
 2 #include<cstring>
 3
#include<algorithm> 4 #include<cstdio> 5 using namespace std; 6 int a[2002][2002],f[2002][2002],L[2002][2002],H[2002][2002],R[2002][2002],ans1,n,m,ans2; 7 int main() 8 {int i,j; 9 cin>>n>>m; 10 for (i=1;i<=n;i++) 11 { 12 for (j=1;j<=m;j++) 13 { 14 scanf("%d",&a[i][j]); 15 } 16 } 17 for (i=1;i<=n;i++) 18 { 19 for (j=1;j<=m;j++) 20 if (a[i][j-1]!=a[i][j]) L[i][j]=L[i][j-1]+1; 21 else L[i][j]=1; 22 for (j=m;j>=1;j--) 23 if (a[i][j+1]!=a[i][j]) R[i][j]=R[i][j+1]+1; 24 else R[i][j]=1; 25 } 26 for (i=2;i<=n;i++) 27 { 28 for (j=1;j<=m;j++) 29 { 30 if (a[i][j]!=a[i-1][j]) 31 { 32 H[i][j]=H[i-1][j]+1; 33 L[i][j]=min(L[i][j],L[i-1][j]); 34 R[i][j]=min(R[i][j],R[i-1][j]); 35 } 36 } 37 } 38 for (i=1;i<=n;i++) 39 { 40 for (j=1;j<=m;j++) 41 { 42 ans2=max(ans2,(L[i][j]+R[i][j]-1)*(H[i][j]+1)); 43 ans1=max(ans1,min(L[i][j]+R[i][j]-1,H[i][j]+1)); 44 } 45 } 46 cout<<ans1*ans1<<endl<<ans2; 47 }

[ZJOI2007]棋盤制作