You are given a grid consisting of n rows each of which is dived into m columns. The rows are numbered from 1 to n from top to bottom, and the columns are numbered from 1 to m from left to right. Each cell is identified by a pair (x, y), which means that the cell is located in the row x and column y.
Your goal is to delete a row x (1 < x < n) and a column y (1 < y < m), after this the matrix will be divided into 4 parts. Let us define the beauty of each part as the maximum value inside it. Your task is to choose x and y such that the difference between the largest and smallest beauties is as minimal as possible. Can you?
Input
The first line contains an integer T (1 ≤ T ≤ 100) specifying the number of test cases.
The first line of each test case contains two integers n and m (3 ≤ n, m ≤ 500), specifying the grid size, in which n is the number of rows and m is the number of columns.
Then n lines follow, each line contains m integers, giving the grid. All values in the grid are between 1 and 10^9 (inclusive).
Output
For each test case, print a single line containing the minimum difference between the largest and smallest beauties after dividing the matrix into 4 parts.
Example
Input
2
3 3
9 5 8
3 4 1
6 2 7
4 4
22 7 3 11
3 1 8 9
5 2 4 3
13 5 6 9
Output
3
13
题意:给你n行m列的矩阵,你可以删去非边缘的一行一列,将矩阵分成四个部分,每个部分所有数的最大数为这一部分的val,再定义差值为四个部分中val最大的部分减val最小的部分为差值,问你删去一行一列之后最小的差值是到多少。
题解:预处理一下4个方向,再枚举每种分割
<mark>注意:数组初始化(╥╯^╰╥)</mark>
#include<cstdio>
#include<cstring>
#include<algorithm>
using namespace std;
int mp[505][505],dp1[505][505],dp2[505][505],dp3[505][505],dp4[505][505];
int main(){
int T,n,m;
scanf("%d",&T);
while(T--){
memset(dp1,0,sizeof(dp1));
memset(dp2,0,sizeof(dp2));
memset(dp3,0,sizeof(dp3));
memset(dp4,0,sizeof(dp4));
scanf("%d%d",&n,&m);
for(int i=1;i<=n;i++){
for(int j=1;j<=m;j++){
scanf("%d",&mp[i][j]);
}
}
//左上角
for(int i=1;i<=n;i++){
for(int j=1;j<=m;j++){
dp1[i][j]=max(mp[i][j],max(dp1[i-1][j],dp1[i][j-1]));
}
}
//右上角
for(int i=1;i<=n;i++){
for(int j=m;j>=1;j--){
dp2[i][j]=max(mp[i][j],max(dp2[i-1][j],dp2[i][j+1]));
}
}
//左下角
for(int i=n;i>=1;i--){
for(int j=1;j<=m;j++){
dp3[i][j]=max(mp[i][j],max(dp3[i+1][j],dp3[i][j-1]));
}
}
//右下角
for(int i=n;i>=1;i--){
for(int j=m;j>=1;j--){
dp4[i][j]=max(mp[i][j],max(dp4[i+1][j],dp4[i][j+1]));
}
}
int ans=999999999;
//枚举分割点
for(int i=2;i<n;i++){
for(int j=2;j<m;j++){
int maxx=max(max(dp1[i-1][j-1],dp2[i-1][j+1]),max(dp3[i+1][j-1],dp4[i+1][j+1]));
int minn=min(min(dp1[i-1][j-1],dp2[i-1][j+1]),min(dp3[i+1][j-1],dp4[i+1][j+1]));
ans=min(maxx-minn,ans);
}
}
printf("%d\n",ans);
}
return 0;
}