Cod sursa(job #597855)

Utilizator Catah15Catalin Haidau Catah15 Data 23 iunie 2011 15:44:20
Problema Struti Scor 80
Compilator cpp Status done
Runda Arhiva de probleme Marime 4.04 kb
#include <iostream>
#include <deque>
#include <cmath>

using namespace std;

#define maxN 1005
#define inf (1 << 30)

deque <int> Dmin, Dmax;
int A[maxN][maxN];
int minim[maxN][maxN], maxim[maxN][maxN];
int Fminim[maxN][maxN], Fmaxim[maxN][maxN];


int main()
{
	freopen ("struti.in", "r", stdin);
	freopen ("struti.out", "w", stdout);
	
	int N, M, P;
	
	scanf ("%d %d %d", &N, &M, &P);
	
	for (int i = 1; i <= N; ++ i)
		for (int j = 1; j <= M; ++ j)
			scanf ("%d", &A[i][j]);
	
	
	while (P --)
	{
		int Dx, Dy;
		
		scanf ("%d %d", &Dx, &Dy);
		
		memset (minim, 0, sizeof (minim));
		memset (maxim, 0, sizeof (maxim));
		memset (Fminim, 0, sizeof (Fminim));
		memset (Fmaxim, 0, sizeof (Fmaxim));
		
		// Dx * Dy
		
		for (int i = 1; i <= N; ++ i)
		{
			Dmin.clear();
			Dmax.clear();
			
			for (int j = 1; j <= M; ++ j)
			{
				if ( ! Dmin.empty() && Dmin.front() <= j - Dx ) Dmin.pop_front();
				if ( ! Dmax.empty() && Dmax.front() <= j - Dx ) Dmax.pop_front();	
				
				while ( ! Dmin.empty() && A[i][Dmin.back()] > A[i][j] ) Dmin.pop_back();
				while ( ! Dmax.empty() && A[i][Dmax.back()] < A[i][j] ) Dmax.pop_back();
				
				Dmin.push_back (j);
				Dmax.push_back (j);
				
				if (j >= Dx)
				{
					minim[i][j] = A[i][Dmin.front()];
					maxim[i][j] = A[i][Dmax.front()];
				}
			}
		}
		
		for (int j = Dx; j <= M; ++ j)
		{
			Dmin.clear();
			Dmax.clear();
			
			for (int i = 1; i <= N; ++ i)
			{
				if ( ! Dmin.empty() && Dmin.front() <= i - Dy ) Dmin.pop_front();
				if ( ! Dmax.empty() && Dmax.front() <= i - Dy ) Dmax.pop_front();	
				
				while ( ! Dmin.empty() && minim[Dmin.back()][j] > minim[i][j] ) Dmin.pop_back();
				while ( ! Dmax.empty() && maxim[Dmax.back()][j] < maxim[i][j] ) Dmax.pop_back();
				
				Dmin.push_back (i);
				Dmax.push_back (i);
				
				if (i >= Dy)
				{
					Fminim[i][j] = minim[Dmin.front()][j];
					Fmaxim[i][j] = maxim[Dmax.front()][j];
				}
			}
		}
		
		int K = 0, sol = inf;
		
		for (int i = Dy; i <= N; ++ i)
			for (int j = Dx; j <= M; ++ j)
				if ( abs (Fmaxim[i][j] - Fminim[i][j] < sol) )
				{
					sol = abs (Fmaxim[i][j] - Fminim[i][j]);
					K = 1;
				}
				else if ( abs (Fmaxim[i][j] - Fminim[i][j] == sol) ) ++ K;
		
		
		
		// Dy * Dx
		
		if (Dx == Dy) goto END;
		
		memset (minim, 0, sizeof (minim));
		memset (maxim, 0, sizeof (maxim));
		memset (Fminim, 0, sizeof (Fminim));
		memset (Fmaxim, 0, sizeof (Fmaxim));
		
		swap (Dx, Dy);
		
		for (int i = 1; i <= N; ++ i)
		{
			Dmin.clear();
			Dmax.clear();
			
			for (int j = 1; j <= M; ++ j)
			{
				if ( ! Dmin.empty() && Dmin.front() <= j - Dx ) Dmin.pop_front();
				if ( ! Dmax.empty() && Dmax.front() <= j - Dx ) Dmax.pop_front();	
				
				while ( ! Dmin.empty() && A[i][Dmin.back()] > A[i][j] ) Dmin.pop_back();
				while ( ! Dmax.empty() && A[i][Dmax.back()] < A[i][j] ) Dmax.pop_back();
				
				Dmin.push_back (j);
				Dmax.push_back (j);
				
				if (j >= Dx)
				{
					minim[i][j] = A[i][Dmin.front()];
					maxim[i][j] = A[i][Dmax.front()];
				}
			}
		}
		
		for (int j = Dx; j <= M; ++ j)
		{
			Dmin.clear();
			Dmax.clear();
			
			for (int i = 1; i <= N; ++ i)
			{
				if ( ! Dmin.empty() && Dmin.front() <= i - Dy ) Dmin.pop_front();
				if ( ! Dmax.empty() && Dmax.front() <= i - Dy ) Dmax.pop_front();	
				
				while ( ! Dmin.empty() && minim[Dmin.back()][j] > minim[i][j] ) Dmin.pop_back();
				while ( ! Dmax.empty() && maxim[Dmax.back()][j] < maxim[i][j] ) Dmax.pop_back();
				
				Dmin.push_back (i);
				Dmax.push_back (i);
				
				if (i >= Dy)
				{
					Fminim[i][j] = minim[Dmin.front()][j];
					Fmaxim[i][j] = maxim[Dmax.front()][j];
				}
			}
		}
		
		
		for (int i = Dy; i <= N; ++ i)
			for (int j = Dx; j <= M; ++ j)
				if ( abs (Fmaxim[i][j] - Fminim[i][j] < sol) )
				{
					sol = abs (Fmaxim[i][j] - Fminim[i][j]);
					K = 1;
				}
				else if ( abs (Fmaxim[i][j] - Fminim[i][j] == sol) ) ++ K;
		
		
		END: ;
		
		printf ("%d %d \n", sol, K);
	}
	
	
	return 0;
}