洛谷 P1387 最大正方形
嗯...
题目链接:https://www.luogu.org/problem/P1387
这道题有很多种做法,可以dp、暴力,而这里介绍的是前缀和做法。
首先输入后维护一个前缀和,然后遍历这个矩阵,当g[i][j]为1,l(边长)初始化为1,然后枚举边长伸长长度k,并且注意边界,然后对于每一个伸长后的矩形面积,进行差分,如果这个面积等于(k + 1) ^ 2,那么说明你现在这个状态它是一个正方形,边长++。然后ans取max即可。
AC代码:
1 #include<cstdio> 2 #include<iostream> 3 4 using namespace std; 5 const int maxn = 205; 6 int n, m, g[maxn][maxn], s[maxn][maxn], l, ans; 7 8 int main(){ 9 scanf("%d%d", &n, &m); 10 for(int i = 1; i <= n; i++){ 11 for(int j = 1; j <= m; j++){ 12 scanf("%d", &g[i][j]); 13 s[i][j] = s[i - 1][j] + s[i][j - 1] - s[i - 1][j - 1] + g[i][j];//前缀和 14 } 15 } 16 for(int i = 1; i <= n; i++){ 17 for(int j = 1; j <= m; j++){ 18 if(g[i][j]){ 19 l = 1;//初始化 20 ans = max(l, ans); 21 for(int k = 1; (k + i) <= n && (k + j) <= m; k++){//枚举伸长长度,判边界 22 if(s[i + k][j + k] - s[i - 1][j + k] - s[i + k][j - 1] + s[i - 1][j - 1] == (k + 1) * (k + 1))//差分判断面积是否相同 23 l++;//边长++ 24 ans = max(ans, l); 25 } 26 } 27 } 28 } 29 printf("%d\n", ans); 30 return 0; 31 }