Cod sursa(job #34825)

Utilizator amadaeusLucian Boca amadaeus Data 21 martie 2007 14:57:25
Problema Struti Scor 20
Compilator cpp Status done
Runda Arhiva de probleme Marime 3.46 kb
// struti - infoarena
#include <cstdio>
#include <deque>
#include <algorithm>
#include <cassert>

#define NX 1001
#define INF 0x3f3f3f3f

#define DBG 0

using namespace std;

struct ent {
	int poz, val;
	ent( int a = 0, int b = 0 ) {
		poz = a, val = b;
	}
};

int a[ NX ][ NX ], c[ NX ][ NX ];

#if DBG
	int matmax[ NX ][ NX ], matmin[ NX ][ NX ];
#endif

int N, M, DX, DY, P;

deque< ent > Cmax[ NX ], Cmin[ NX ], Lmax, Lmin;

inline
void umin( int& x, int y ) {
	if( x > y )
		x = y;
}

inline
void umax( int&x, int y ) {
	if( x < y )
		x = y;
}

ent rez() {
	int x, r, i, j, cnt;
/*
	for( i = 1; i < DX; i++ )
		for( j = 1; j <= M; j++ ) {
			x = a[i][j];
			while( !Cmax[j].empty() && Cmax[j].back().val < x )
				Cmax[j].pop_back();
			Cmax[j].push_back( ent( i, x ) );
			
			while( !Cmin[j].empty() && Cmin[j].back().val > x )
				Cmin[j].pop_back();
			Cmin[j].push_back( ent( i, x ) );
		}
*/
	r = INF;
	for( j = 1; j <= M; j++ ) {
		Cmax[j].clear();
		Cmin[j].clear();
	}
	for( i = 1; i <= N; i++ ) {
		Lmax.clear();
		Lmin.clear();
		for( j = 1; j <= M; j++ ) {
			x = a[i][j];

			if( !Cmax[j].empty() && Cmax[j].front().poz < i - DX + 1 )
				Cmax[j].pop_front();

			while( !Cmax[j].empty() && Cmax[j].back().val < x )
				Cmax[j].pop_back();

			Cmax[j].push_back( ent( i, x ) );

			if( !Cmin[j].empty() && Cmin[j].front().poz < i - DX + 1 )
				Cmin[j].pop_front();

			while( !Cmin[j].empty() && Cmin[j].back().val > x )
				Cmin[j].pop_back();

			Cmin[j].push_back( ent( i, x ) );

#if DBG
			matmax[i][j] = Cmax[j].front().val;
			matmin[i][j] = Cmin[j].front().val;
#endif
			if( i < DX )
				continue;

			x = Cmax[j].front().val;
			if( !Lmax.empty() && Lmax.front().poz < j - DY + 1 )
				Lmax.pop_front();
			while( !Lmax.empty() && Lmax.back().val < x )
				Lmax.pop_back();
			Lmax.push_back( ent( j, x ) );

			x = Cmin[j].front().val;
			if( !Lmin.empty() && Lmin.front().poz < j - DY + 1 )
				Lmin.pop_front();
			while( !Lmin.empty() && Lmin.back().val > x )
				Lmin.pop_back();
			Lmin.push_back( ent( j, x ) );

			if( i >= DX && j >= DY ) {
#if DBG
				int vmin, vmax;
				vmin = INF; vmax = 0;
				for( int ii = i - DX + 1; ii <= i; ii++ )
					for( int jj = j - DY + 1; jj <= j; jj++ ) {
						umin( vmin, a[ii][jj] );
						umax( vmax, a[ii][jj] );
					}
				assert( vmin == Lmin.front().val );
				assert( vmax == Lmax.front().val );
#endif
				x = Lmax.front().val - Lmin.front().val;
				c[ i - DX + 1 ][ j - DY + 1 ] = x;
				umin( r, x );
			}
		}
	}
#if DBG
	printf( "=============\n" );
	printf( "DX = %d    DY = %d\n", DX, DY );
	for( i = 1; i<= N; i++ ) {
		for( j = 1; j <= M; j++ )
			printf( "%3d", matmax[i][j] );
		printf( "\n\n" );
	}
#endif
	cnt = 0;
	for( i = 1; i <= N - DX + 1; i++ )
		for( j = 1; j <= M - DY + 1; j++ )
			if( c[i][j] == r )
				cnt++;
	return ent( r, cnt );
}

void cit() {
	int i, j;
 	ent x, y;

	scanf( "%d%d%d", &M, &N, &P );

	for( i = 1; i <= N; i++ )
		for( j = 1; j <= M; j++ )
			scanf( "%d", &a[i][j] );

	for( ; P; P-- ) {
		scanf( "%d%d", &DX, &DY );
		x = rez(); y = ent( 0, INF );
		if( DX != DY ) {
			swap( DX, DY );
			y = rez();
			if( x.poz > y.poz )
				x = y;
			if( x.poz == y.poz )
				x.val += y.val;
		}
		
		printf( "%d %d\n", x.poz, x.val );
	}
}

int main() {
	freopen( "struti.in", "r", stdin );
	freopen( "struti.out", "w", stdout );

	cit();

	return 0;
}