• MINSUB


    MINSUB - Largest Submatrix

    no tags 

    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
    ",ret,ma);
        }
        return 0;
    }
  • 相关阅读:
    JS优先队列排序。出队时,先找出优先级最高的元素,再按照先进先出出队。
    使用队列对数组排列,基数排序
    一个用JS数组实现的队列
    使用栈判断给定字符串是否是回文的算法
    使用js栈stack类的实现
    Bootstrap篇:弹出框和提示框效果以及代码展示
    一个漂亮的php验证码类
    jquery单选框radio绑定click事件实现和是否选中的方法
    phpQuery—基于jQuery的PHP实现
    PHP的函数-----生成随机数、日期时间函数
  • 原文地址:https://www.cnblogs.com/dyzll/p/6471993.html
Copyright © 2020-2023  润新知