洛谷 1387 最大正方形
比 创意吃鱼法要简单一些啊
mp[i][j] 存题目给的图
a[i][j] 表示从(i,j)往左最多可以连续到达几个为1的格子
b[i][j] 表示从(i,j)往上最多可以连续到达几个为1的格子
f[i][j] 表示以(i,j)为右下角的最大的不含0的正方形的边长
转移方程: if(mp[i][j]) f[i][j]=min(f[i-1][j-1]+1,min(a[i][j],b[i][j]));
CODE
View Code1 #include<iostream> 2 #include<cstdio> 3 #define go(i,a,b) for(register int i=a;i<=b;i++) 4 #define M 100+10 5 using namespace std; 6 int read() 7 { 8 int x=0,y=1;char c=getchar(); 9 while(c<'0'||c>'9') {if(c=='-') y=-1;c=getchar();} 10 while(c>='0'&&c<='9') {x=(x<<1)+(x<<3)+c-'0';c=getchar();} 11 return x*y; 12 } 13 int n,m,ans,mp[M][M],a[M][M],b[M][M],f[M][M]; //a:--- b:| 14 int main() 15 { 16 n=read();m=read(); 17 go(i,1,n) go(j,1,m) mp[i][j]=read(); 18 go(i,1,n) go(j,1,m) 19 { 20 if(mp[i][j]) 21 { 22 a[i][j]=a[i][j-1]+1; 23 b[i][j]=b[i-1][j]+1; 24 f[i][j]=min(a[i][j],b[i][j]); 25 if(i>1&&j>1) f[i][j]=min(f[i][j],f[i-1][j-1]+1); 26 ans=max(ans,f[i][j]); 27 } 28 } 29 printf("%d",ans); 30 return 0; 31 }
光伴随的阴影