先上题目
输入一个n表示有一个n*n的矩阵,然后输入矩阵的内容,"H"代表0,"."代表1,求出最大的填满1的正方形的面积。
这是一道dp。
定义一个数组s[][]代表以(1,1)和(i,j)为对角线的矩形中全为1的的矩形的边长。
再定义一个数组row[][]代表(i,0)-(i,j)连续的1最长的长度;
再定义一个数组col[][]代表(0,j)-(i,j)连续的1最长的长度;
则
if((i,j)==0) row[i][j]=col[i][j]=0;
else
{
row[i][j]=row[i][j-1]+1;
col[i][j]=col[i-1][j]+1;
}
对于s[i][j],就会是s[i-1][j-1]+(i,j) ,row[i][j] ,col[i][j] 中的最小值,因为需要限制图形是正方形。
最后只要扫一下s[][],找出里面最大的值,就是所求的正方形的边长,再平方就是所求的面积大小。
目测有更加好的方法,这种方法在OJ上跑了一下要65ms。= =
上代码
#include <stdio.h> #include <string.h> #define MAX 1100 #define max(x,y) (x>y ? x: y) using namespace std; int s[MAX][MAX],col[MAX][MAX],row[MAX][MAX]; char ch[MAX][MAX]; int min(int x,int y,int z) { if(x<=y && x<=z) return x; else if(y<=x && y<=z) return y; return z; } int main() { int i,j,t,n,maxn; char o; scanf("%d",&n); o=getchar(); memset(s,0,sizeof(s)); memset(ch,0,sizeof(ch)); memset(col,0,sizeof(col)); memset(row,0,sizeof(row)); for(i=0;i<n;i++) { gets(ch[i]); } for(t=0;t<n;t++) { i=t+1; j=0; while(ch[t][j]!='\0') { if(ch[t][j]=='H') { j++; s[i][j]=0; } else { j++; s[i][j]=1; row[i][j]=row[i][j-1]+1; col[i][j]=col[i-1][j]+1; } } } for(i=1;i<=n;i++) { for(j=1;j<=n;j++) { s[i][j]=min(s[i-1][j-1]+1,col[i][j],row[i][j]); } } maxn=0; for(i=1;i<=n;i++) { for(j=1;j<=n;j++) { //printf("%d ",s[i][j]); maxn=max(maxn,s[i][j]); } //printf("\n"); } printf("%d\n",maxn*maxn); return 0; }