Max Sub-matrix
教练找的题目,目前样列过了
题意:找子矩阵的最大周长
思路:先离散每列,再枚举列(n*n),在当前枚举的两列之间求每行的和(n*n*n),但是开两个数组,一个包含两列上的元素 一个不包含,这样可以处理出前i行当前这两列上的元素和。 当前两列中每行元素和知道 两列上前i项和知道就可以找出最大值
1 #include <iostream> 2 #include <cstdio> 3 #include <algorithm> 4 #include <list> 5 #include <map> 6 #include <stack> 7 #include <vector> 8 #include <cstring> 9 #include <sstream> 10 #include <string> 11 #include <cmath> 12 #include <queue> 13 #include <stdlib.h> 14 #include <conio.h> 15 #include <bits/stdc++.h> 16 using namespace std; 17 #define clc(a,b) memset(a,b,sizeof(a)) 18 #define inf 0x3f3f3f3f 19 const int N=100010; 20 const int MOD = 1e9+7; 21 #define LL long long 22 void fre() { 23 freopen("in.txt","r",stdin); 24 } 25 26 inline int r() { 27 int x=0,f=1;char ch=getchar(); 28 while(ch>'9'||ch<'0') {if(ch=='-') f=-1;ch=getchar();} 29 while(ch>='0'&&ch<='9') { x=x*10+ch-'0';ch=getchar();}return x*f; 30 } 31 int T,R ,s; 32 33 struct node{ 34 int x,y,w; 35 node(){} 36 node(int xx,int yy,int ww):x(xx),y(yy),w(ww){} 37 bool operator <(const node &a)const{ 38 return x<a.x; 39 } 40 }p[110]; 41 42 int c; 43 LL sum; 44 int col[110]; 45 LL l[110],row[110],row1[110]; 46 void init(){ 47 R=r(),s=r(); 48 clc(col,0); 49 clc(l,0); 50 clc(row,0); 51 clc(row1,0); 52 c=0; 53 sum=0; 54 for(int i=0;i<R;i++){ 55 for(int j=0;j<s;j++){ 56 int x; 57 x=r(); 58 if(x){ 59 sum+=x; 60 p[c]=node(i,j,x); 61 col[c++]=j; 62 } 63 } 64 } 65 } 66 67 LL work(){ 68 sort(p,p+c); 69 sort(col,col+c); 70 int n=unique(col,col+c)-col; 71 if(n<=2) return sum; 72 LL ans=0; 73 for(int i=0;i<n;i++){ 74 for(int j=i+1;j<n;j++){ 75 int cmin=col[i],cmax=col[j]; 76 int cnt=0; 77 for(int k=0;k<c;k++){ 78 if(k==0||p[k].x!=p[k-1].x){ 79 cnt++; 80 row[cnt]=row1[cnt]=0; 81 l[cnt] = (cnt==1)?0:l[cnt-1]+row1[cnt-1]-row[cnt-1]; 82 } 83 int cnow=p[k].y; 84 int cost=p[k].w; 85 if(cnow>cmin&&cnow<cmax) row[cnt]+=cost; 86 if(cnow>=cmin&&cnow<=cmax) row1[cnt]+=cost; 87 } 88 // for(int i=1;i<=cnt;i++){ 89 // printf("%d ",l[i]); 90 // } 91 // cout<<endl; 92 // getch(); 93 if(cnt<=2) return sum; 94 LL maxn=0; 95 for(int k=1;k<=cnt;k++){ 96 ans=max(ans,l[k]+row1[k]+maxn); 97 maxn=max(maxn,row[k]-l[k]); 98 } 99 } 100 } 101 return ans; 102 } 103 104 int main(){ 105 // fre(); 106 T=r(); 107 while(T--){ 108 init(); 109 LL ans=work(); 110 printf("%lld ",ans); 111 } 112 return 0; 113 }