1. 程式人生 > >Gym - 101972G Minimax 預處理+列舉

Gym - 101972G Minimax 預處理+列舉

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 (xy), 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 109 (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

題意:選定一個元素刪除其所在行所在列把圖分為四部分,求一個點分割後的四部分每一部分的最大值,取出來得到四個,這四個求一下最大最小的差,讓這個差儘可能的小

題解:預處理一下4個方向,列舉每個位置即可(除了邊界),注意陣列清0

#include<iostream>
#include<cstdio>
#include<algorithm>
#include<cstring>
using namespace std;
const int N=510;
typedef long long ll;
const ll mod=1e9+7;
int m1[510][510],m2[510][510],m3[510][510],m4[510][510];
int n,m;
int main()
{
	int T,x;
	scanf("%d",&T);
	while(T--)
	{
		scanf("%d%d",&n,&m);
		memset(m1,0,sizeof(m1));
		memset(m2,0,sizeof(m2));
		memset(m3,0,sizeof(m3));
		memset(m4,0,sizeof(m4));
		for(int i=1;i<=n;i++)
		{
			for(int j=1;j<=m;j++)
			{
				scanf("%d",&x);
				m1[i][j]=m2[i][j]=m3[i][j]=m4[i][j]=x;
			}
		}
		for(int i=1;i<=n;i++)
			for(int j=1;j<=m;j++)
			 m1[i][j]=max(m1[i][j],max(m1[i-1][j],m1[i][j-1]));
			 
		for(int i=1;i<=n;i++)
			for(int j=m;j>=1;j--)
			 m2[i][j]=max(m2[i][j],max(m2[i-1][j],m2[i][j+1]));
			 
		for(int i=n;i>=1;i--)
			for(int j=1;j<=m;j++)
				m3[i][j]=max(m3[i][j],max(m3[i+1][j],m3[i][j-1]));
				
		for(int i=n;i>=1;i--)
			for(int j=m;j>=1;j--)
			 m4[i][j]=max(m4[i][j],max(m4[i+1][j],m4[i][j+1]));
			 
		int ans=1e9+1;
		for(int i=2;i<n;i++)
		{
			for(int j=2;j<m;j++)
			{
				int maxx=-1,minn=1e9+5;
				
				maxx=max(maxx,m1[i-1][j-1]);
				maxx=max(maxx,m2[i-1][j+1]);
				maxx=max(maxx,m3[i+1][j-1]);
				maxx=max(maxx,m4[i+1][j+1]);
				
				minn=min(minn,m1[i-1][j-1]);
				minn=min(minn,m2[i-1][j+1]);
				minn=min(minn,m3[i+1][j-1]);
				minn=min(minn,m4[i+1][j+1]);
				
				ans=min(ans,maxx-minn);
			}
		}
		printf("%d\n",ans);
	}
	return 0;
}