Live2d Test Env

HihoCoder 1502 : 最大子矩阵 (双指针)

描述

给定一个NxM的矩阵A和一个整数K,小Hi希望你能求出其中最大(元素数目最多)的子矩阵,并且该子矩阵中所有元素的和不超过K。

输入

第一行包含三个整数N、M和K。

以下N行每行包含M个整数,表示A。

对于40%的数据,1 <= N, M <= 10  

对于100%的数据,1 <= N, M <= 250 1 <= K <= 2147483647 1 <= Aij <= 10000

输出

满足条件最大的子矩阵所包含的元素数目。如果没有子矩阵满足条件,输出-1。

样例输入

3 3 9
1 2 3  
2 3 4  
3 4 5

样例输出

4 

 

由于A>=1满足区间和的单调性。所以可以用双指针,即枚举矩形的上下边界,然后移动左右边界。

qwq,开始看“元素”,我以为要去重,所以做复杂了。

 (总的来说,很多可以二分做的题,可以用双指针,效率更高。

#include<cstdio>
#include<cstdlib>
#include<cstring>
#include<iostream>
#include<algorithm>
using namespace std;
const int maxn=300;
int N,M,K,a[maxn][maxn],sum[maxn][maxn];
int vis[10010],num,Now,ans=-1;
int main()
{
    int i,j,k,L,R;
    scanf("%d%d%d",&N,&M,&K);
    for(i=1;i<=N;i++)
      for(j=1;j<=M;j++){
        scanf("%d",&a[i][j]);
        sum[i][j]=sum[i-1][j]+a[i][j];
    }
    
    for(i=1;i<=N;i++)
      for(j=i;j<=N;j++){ 
         memset(vis,0,sizeof(vis));
         num=0; Now=0;
         for(R=1,L=1;R<=M;R++){
             num+=j-i+1; Now+=sum[j][R]-sum[i-1][R];
             while(Now>K&&L<=R) {
                num-=j-i+1;
                Now-=sum[j][L]-sum[i-1][L];
                L++;
             }
             if(Now<=K&&L<=R) ans=max(ans,num);
         }
    }
    printf("%d\n",ans);
    return 0;
}

 

posted @ 2018-02-20 17:07  nimphy  阅读(345)  评论(0编辑  收藏  举报