题解:by Mercury_Lc
阎小罗的矩阵给的n和m都不超过300,枚举一下所有情况就可以了,用前缀和来储存。数组a[x][y]代表前x行前y列的和是多少,那么枚举每一种切割的方式就可以。注意一下切掉的第x行和第y列的数都是不计入的,减掉的时候别重复或者遗漏了。
参考代码:
#include <stdio.h>
#include <stdlib.h>
#include <string.h>
#include <assert.h>
typedef long long ll;
ll a[505][505];
ll min(ll x, ll y)
{
if(x > y)
return y;
else
return x;
}
ll max(ll x, ll y)
{
if(x < y)
return y;
else
return x;
}
int main()
{
ll t, n, m, i, j;
scanf("%lld", &t);
assert(1 <= t && t <= 10);
while(t--)
{
memset(a, 0, sizeof(a));
scanf("%lld %lld", &n, &m);
assert(n >= 3 && n <= 300 && m >= 3 && m <= 300);
for(i = 1; i <= n; i++)
{
for(j = 1; j <= m; j++)
{
scanf("%lld", &a[i][j]);
assert(a[i][j] >= 0 && a[i][j] <= 1000000000);
a[i][j] += a[i][j - 1];
}
for(j = 1; j <= m; j++)
{
a[i][j] += a[i - 1][j];
}
}
ll ans = 0x3fffffffffff;
for(i = 2; i < n; i++)
{
for(j = 2; j < m; j++)
{
ll aa, bb, cc, dd;
aa = a[i - 1][j - 1];
bb = a[i - 1][m] - a[i - 1][j];
cc = a[n][j - 1] - a[i][j - 1];
dd = a[n][m] - a[n][j] - (a[i][m] - a[i][j]);
ll maxx = max(max(aa, bb), max(cc, dd));
ll minn = min(min(aa, bb), min(cc, dd));
ans = min(maxx - minn, ans);
}
}
printf("%lld\n", ans);
}
return 0;
}