标签:
题意:
现在有一个n*m的矩阵A,在A中找一个H*H的正方形,使得其面积最大且该正方形元素的和不大于 limit。
思路: 水题
预处理矩形元素和,然后二分枚举最大边长,然后把这边长在整个矩形中试一遍(O(n*m))看是否符合。总时间复杂度O(n*m*log(min(n,m))) 可暴
code:
#include<cstdio> #include<iostream> #include<sstream> #include<cstring> #include<algorithm> #include<vector> #include<string> #include<queue> #include<map> #include<set> #include<cmath> #include<cctype> #include<cstdlib> using namespace std; #define INF 0x3f3f3f3f #define PI acos(-1.0) #define mem(a, b) memset(a, b, sizeof(a)) #define mod 1000000007 typedef pair<int,int> pii; typedef long long LL; //------------------------------ const int maxn = 1005; int n,m,limit; int pre[maxn][maxn]; int maze[maxn][maxn]; void deal(){ memset(pre, 0, sizeof(pre)); for(int i = 1; i <= m; i++){ pre[1][i] = pre[1][i-1] + maze[1][i]; } for(int i = 2; i <= n; i++){ int tmp = 0; for(int j = 1; j <= m; j++){ tmp += maze[i][j]; pre[i][j] = pre[i-1][j] + tmp; } } } void init(){ scanf("%d%d%d",&n,&m,&limit); for(int i = 1; i <= n; i++){ for(int j = 1; j <= m; j++){ scanf("%d",&maze[i][j]); } } deal(); } bool ok(int x){ for(int i = 1; i <= n-x+1; i++){ for(int j = 1; j <= m-x+1; j++){ if(pre[i+x-1][j+x-1] - pre[i-1][j+x-1] - pre[i+x-1][j-1] + pre[i-1][j-1] <= limit) return true; } } return false; } void solve(){ int lb = 0, ub = min(n,m); while(lb <= ub){ int mid = (lb+ub) / 2; if(ok(mid)) lb = mid+1; else ub = mid-1; } printf("%d\n",ub * ub); } int main(){ int t; scanf("%d",&t); while(t--){ init(); solve(); } return 0; }
我的二分出了点小问题,真实比了狗了...T_T
标签:
原文地址:http://blog.csdn.net/u013382399/article/details/45768587