题目:Garbage Heap
思路:三维前缀和。
注意:开 long long。
代码:
#include <cstdio>
#include <iostream>
#include <algorithm>
#include <stack>
#include <queue>
#include <deque>
#include <set>
#include <cstring>
#include <map>
#include <cmath>
using namespace std;
#define maxa 20
#define ll long long
int A,B,C;
ll a[maxa+5][maxa+5][maxa+5]={0}; //a[j][k][i] : 其中两个顶点为(i,0,0)和(i,j,k)的长方体的数字和
void make_on(ll* on,int b,int c,int y,int z){
for(int i=1;i<=A;i++){
on[i]=on[i-1]+a[y][z][i]+a[b][c][i]-a[y][c][i]-a[b][z][i];
}
}
int main() {
int T;
scanf("%d",&T);
while(T--){
scanf("%d%d%d",&A,&B,&C);
for(int i=1;i<=A;i++){
for(int j=1;j<=B;j++){
for(int k=1;k<=C;k++){
scanf("%lld",&a[j][k][i]);
a[j][k][i]=a[j][k][i]+a[j-1][k][i]+a[j][k-1][i]-a[j-1][k-1][i];
}
}
}
ll ans=-(1LL<<60);
for(int b=0;b<=B;b++){ //枚举所选长方体的两顶点的y,z坐标
for(int c=0;c<=C;c++){
for(int y=b+1;y<=B;y++){
for(int z=c+1;z<=C;z++){
ll on[maxa+5]={0};
make_on(on,b,c,y,z);
int x=0;
for(int a=1;a<=A;a++){ //横坐标
ans=max(ans,on[a]-on[x]);
if(on[x]>on[a]) x=a;
}
}
}
}
}
printf("%lld\n",ans);
if(T) printf("\n");
}
return 0;
}