Largest Square
Accept:24 Submit:50
Time Limit:5000MS Memory Limit:65536KB
Description
Give you a N*N(1≤N≤2000)Square.For each grid in the square,its color is red or black.Your task is to find a largest red square.
InputFormat
The first line is an integer T(1≤T≤5) indicating the case number.
For each case,the first line is N,then next N lines describes the square.If a_ij=0,indicating a_ijis black,if a_ij=1,indicating a_ij is red.
OutputFormat
For each case,output an integer which is the leng of the side of the largest red square.
SampleInput
2
3
101
000
111
3
111
111
111
SampleOutput
1
3
新生排位赛第三场的E题,比赛时参考了POJ1050的思想,把每一个二维的正方形暴力转化为一维的数组来处理,结果以6003ms的TLE宣告失败。
听学长讲了以后才知道,这题可以动态规划处理,用一个数组dp[i][j]记录以(i,j)为右下角可以构成的最大红色正方形的边长。
具体的状态转移可以参看代码中的f()函数。
1 #include<iostream> 2 #include<cstdio> 3 4 using namespace std; 5 6 int n; 7 int g[2001][2001]; 8 int dp[2001][2001]; 9 10 int Min(int a,int b) 11 { 12 return a<b?a:b; 13 } 14 15 int f(int x,int y) 16 { 17 if(dp[x][y]!=-1) 18 return dp[x][y]; 19 if(g[x][y]==0) 20 return dp[x][y]=0; 21 if(f(x-1,y)==f(x,y-1)) 22 if(dp[x-1][y]==0) 23 return dp[x][y]=1; 24 else 25 { 26 if(g[x-dp[x-1][y]][y-dp[x-1][y]]==1) 27 return dp[x][y]=dp[x-1][y]+1; 28 else 29 return dp[x][y]=dp[x-1][y]; 30 } 31 else 32 if(dp[x][y-1]==0||dp[x-1][y]==0) 33 return dp[x][y]=1; 34 else 35 return dp[x][y]=Min(dp[x-1][y],dp[x][y-1])+1; 36 } 37 38 39 int main() 40 { 41 int t; 42 43 scanf("%d",&t); 44 45 while(t--) 46 { 47 char s[2050]; 48 scanf("%d",&n); 49 getchar(); 50 51 memset(dp,-1,sizeof(dp)); 52 for(int i=0;i<=n;i++) 53 dp[i][0]=0; 54 for(int j=0;j<=n;j++) 55 dp[0][j]=0; 56 57 for(int i=1;i<=n;i++) 58 { 59 gets(s); 60 for(int j=1;j<=n;j++) 61 g[i][j]=s[j-1]-'0'; 62 } 63 for(int i=1;i<=n;i++) 64 for(int j=1;j<=n;j++) 65 f(i,j); 66 int ans=0; 67 for(int i=1;i<=n;i++) 68 for(int j=1;j<=n;j++) 69 if(dp[i][j]>ans) 70 ans=dp[i][j]; 71 printf("%d ",ans); 72 } 73 74 return 0; 75 }