1. 程式人生 > >HihoCoder 1502 : 最大子矩陣 (雙指針)

HihoCoder 1502 : 最大子矩陣 (雙指針)

一個 return lib size algo 上下 cor pri post

描述

給定一個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; }

HihoCoder 1502 : 最大子矩陣 (雙指針)