Cod sursa(job #981530)

Utilizator alex_unixPetenchea Alexandru alex_unix Data 7 august 2013 14:16:30
Problema Struti Scor 100
Compilator cpp Status done
Runda Arhiva de probleme Marime 2.03 kb

#include <cstdio>
#include <queue>
#include <algorithm>
#include <utility>

const int MAX_SIZE(1001);
const int MAX_VALUE(1 << 30);

int n, m, p, Best, Count;
int Matrix [MAX_SIZE] [MAX_SIZE];
int MinMatrix [MAX_SIZE] [MAX_SIZE];
int MaxMatrix [MAX_SIZE] [MAX_SIZE];
std::deque<int> Min, Max;



inline void Compute (const int DX, const int DY)
{
	int i, j;
	for (i = 1 ; i <= n ; ++i)
	{
		Min.clear();
		Max.clear();
		for (j = 1 ; j <= m ; ++j)
		{
			while (!Min.empty() && Matrix[i][j] < Matrix[i][Min.back()])
				Min.pop_back();
			Min.push_back(j);
			while (!Max.empty() && Matrix[i][j] > Matrix[i][Max.back()])
				Max.pop_back();
			Max.push_back(j);
			if (j >= DY)
			{
				while (Max.front() <= j - DY)
					Max.pop_front();
				MaxMatrix[i][j] = Matrix[i][Max.front()];
				while (Min.front() <= j - DY)
					Min.pop_front();
				MinMatrix[i][j] = Matrix[i][Min.front()];
			}
		}
	}
	for (j = DY ; j <= m ; ++j)
	{
		Min.clear();
		Max.clear();
		for (i = 1 ; i <= n ; ++i)
		{
			while (!Min.empty() && MinMatrix[i][j] < MinMatrix[Min.back()][j])
				Min.pop_back();
			Min.push_back(i);
			while (!Max.empty() && MaxMatrix[i][j] > MaxMatrix[Max.back()][j])
				Max.pop_back();
			Max.push_back(i);
			if (i >= DX)
			{
				while (Max.front() <= i - DX)
					Max.pop_front();
				while (Min.front() <= i - DX)
					Min.pop_front();
				if (MaxMatrix[Max.front()][j] - MinMatrix[Min.front()][j] < Best)
				{
					Best = MaxMatrix[Max.front()][j] - MinMatrix[Min.front()][j];
					Count = 1;
				}
				else if (MaxMatrix[Max.front()][j] - MinMatrix[Min.front()][j] == Best)
					++Count;
			}
		}
	}
}

int main (void)
{
	std::freopen("struti.in","r",stdin);
	std::freopen("struti.out","w",stdout);
	std::scanf("%d %d %d\n",&n,&m,&p);
	int i, j;
	for (i = 1 ; i <= n ; ++i)
		for (j = 1 ; j <= m ; ++j)
			std::scanf("%d",&Matrix[i][j]);
	while (p)
	{
		std::scanf("%d %d",&i,&j);
		Best = MAX_VALUE;
		Count = 0;
		Compute(i,j);
		if (i != j)
			Compute(j,i);
		std::printf("%d %d\n",Best,Count);
		--p;
	}
	std::fclose(stdin);
	std::fclose(stdout);
	return 0;
}