标签:
这题的关键就是预处理矩阵利用
dp[i][j] = dp[i - 1][j] + dp[i][j - 1] - dp[i-1][j-1]
递推出矩阵,使得我们以后每次已经利用O(1)的复杂度计算任意一块矩阵
之后枚举正方形左上角的坐标二分边长,时间复杂度为n^2 log(n)
#include<iostream> #include<cstdio> #include<cstring> using namespace std; const int maxn = 1005; int n,m,t; int mat[maxn][maxn]; int ans[maxn][maxn]; int get_value(int x1,int y1,int x2,int y2){ return ans[x2][y2] - (ans[x1 - 1][y2] + ans[x2][y1 - 1] - ans[x1 - 1][y1 - 1]); } void solve(){ int l = 1,r = min(n,m); int rans = 0; while(l <= r){ int h = (l + r) >> 1; int ok = 0; for(int i = 1; i + h - 1<= n; i++){ for(int j = 1; j + h - 1 <= m; j++){ int e = get_value(i,j,i + h - 1,j + h - 1); if(e <= t){ ok = 1; break; } } if(ok) break; } if(ok){ rans = h; l = h +1; } else r = h - 1; } printf("%d\n",rans * rans); } int main(){ int T; scanf("%d",&T); while(T--){ memset(ans,0,sizeof(ans)); scanf("%d%d%d",&n,&m,&t); for(int i = 1; i <= n; i++) for(int j = 1; j <= m; j++) scanf("%d",&mat[i][j]); for(int i = 1; i <= n; i++) for(int j = 1; j <= m; j++) ans[i][j] = ans[i - 1][j] + ans[i][j - 1] - ans[i - 1][j - 1] + mat[i][j]; solve(); } return 0; }
标签:
原文地址:http://blog.csdn.net/u013451221/article/details/45750069