MINSUB - Largest Submatrix
MINSUB - Largest Submatrix
You are given an matrix M (consisting of nonnegative integers) and an integer K. For any submatrix of M' of M define min(M') to be the minimum value of all the entries of M'. Now your task is simple: find the maximum value of min(M') where M' is a submatrix of M of area at least K (where the area of a submatrix is equal to the number of rows times the number of columns it has).
Input
The first line contains a single integer T (T ≤ 10) denoting the number of test cases, T test cases follow. Each test case starts with a line containing three integers, R (R ≤ 1000), C (C ≤ 1000) and K (K ≤ R * C) which represent the number of rows, columns of the matrix and the parameter K. Then follow R lines each containing C nonnegative integers, representing the elements of the matrix M. Each element of M is ≤ 10^9
Output
For each test case output two integers: the maximum value of min(M'), where M' is a submatrix of M of area at least K, and the maximum area of a submatrix which attains the maximum value of min(M'). Output a single space between the two integers.
Example
Input: 2 2 2 2 1 1 1 1 3 3 2 1 2 3 4 5 6 7 8 9 Output: 1 4 8 2
分析:首先二分答案M,其次改写成01矩阵,这样变成求最大的全1子矩阵;
最大全1子矩阵那么可以单调栈解决;
代码:
#include <iostream> #include <cstdio> #include <cstdlib> #include <cmath> #include <algorithm> #include <climits> #include <cstring> #include <string> #include <set> #include <bitset> #include <map> #include <queue> #include <stack> #include <vector> #define rep(i,m,n) for(i=m;i<=n;i++) #define mod 1000000007 #define inf 0x3f3f3f3f #define vi vector<int> #define pb push_back #define mp make_pair #define fi first #define se second #define ll long long #define pi acos(-1.0) #define pii pair<int,int> #define sys system("pause") const int maxn=1e3+10; const int N=1e3+10; using namespace std; ll gcd(ll p,ll q){return q==0?p:gcd(q,p%q);} ll qpow(ll p,ll q){ll f=1;while(q){if(q&1)f=f*p;p=p*p;q>>=1;}return f;} int n,m,k,t,qu[maxn],a[maxn][maxn],v[maxn][maxn],le[maxn],ret,ma,now; bool ok(int x) { now=0; int i,j; rep(i,1,n)rep(j,1,m)v[i][j]=(a[i][j]>=x?v[i-1][j]+1:0); rep(i,1,n) { rep(j,1,m+1) { if(!qu[0])qu[++qu[0]]=v[i][j],le[qu[0]]=j; else if(v[i][j]>qu[qu[0]])qu[++qu[0]]=v[i][j],le[qu[0]]=j; else if(v[i][j]<qu[qu[0]]) { int tmp; while(qu[0]>=1&&v[i][j]<=qu[qu[0]]) { now=max(now,(j-le[qu[0]])*qu[qu[0]]); tmp=le[qu[0]]; qu[0]--; } qu[++qu[0]]=v[i][j]; le[qu[0]]=tmp; } } qu[0]--; } return now>=k; } int main() { int i,j; scanf("%d",&t); while(t--) { scanf("%d%d%d",&n,&m,&k); rep(i,1,n)rep(j,1,m)scanf("%d",&a[i][j]); int l=1,r=1e9; while(l<=r) { int mid=l+r>>1; if(ok(mid))ret=mid,ma=now,l=mid+1; else r=mid-1; } printf("%d %d\n",ret,ma); } return 0; }