Pagini recente » Ciorna | Cod sursa (job #1633890) | Cod sursa (job #2721622) | Cod sursa (job #403607) | Cod sursa (job #1464740)
#include <cstdio>
#include <deque>
#include <cstring>
#include <iostream>
using namespace std;
const int MAXNM = 1010;
const int MAXREAD = 100000;
const int INF = 0x3f3f3f3f;
int N, M, P;
int a[MAXNM][MAXNM];
int minim[MAXNM][MAXNM];
int maxim[MAXNM][MAXNM];
char r[MAXREAD];
int p = MAXREAD - 1;
int dif, var;
deque<int> Qmax, Qmin;
void Solve( int& dif, int& var, int L, int C );
void Get( int& x );
void Next();
void Write( int a[MAXNM][MAXNM] );
int main()
{
freopen( "struti.in", "r", stdin );
freopen( "struti.out", "w", stdout );
int i, j, x, y;
Get(N); Get(M); Get(P);
// cout << N << ' ' << M << ' ' << P; cin.get();
for ( i = 1; i <= N; i++ )
for ( j = 1; j <= M; j++ )
{
Get(x);
a[i][j] = x;
}
// Write(a);
for ( i = 1; i <= P; i++ )
{
Get(x); Get(y);
dif = INF;
var = 0;
Solve( dif, var, x, y );
if ( x != y )
Solve( dif, var, y, x );
printf( "%d %d\n", dif, var );
}
fclose(stdin);
fclose(stdout);
return 0;
}
void Solve( int& dif, int& var, int L, int C )
{
int i, j, d;
memset( minim, 0, sizeof(minim) );
memset( maxim, 0, sizeof(maxim) );
for ( i = 1; i <= N; i++ )
{
Qmin.clear();
Qmax.clear();
for ( j = 1; j <= M; j++ )
{
while ( !Qmin.empty() && Qmin.front() < j - C + 1 )
Qmin.pop_front();
while ( !Qmin.empty() && a[i][j] < a[i][Qmin.back()] )
Qmin.pop_back();
Qmin.push_back(j);
if ( j >= C )
{
minim[i][j] = a[i][Qmin.front()];
}
while ( !Qmax.empty() && Qmax.front() < j - C + 1 )
Qmax.pop_front();
while ( !Qmax.empty() && a[i][j] > a[i][Qmax.back()] )
Qmax.pop_back();
Qmax.push_back(j);
if ( j >= C )
{
maxim[i][j] = a[i][Qmax.front()];
}
}
}
/* Write(maxim);
Write(minim); */
for ( j = 1; j <= M; j++ )
{
Qmin.clear();
Qmax.clear();
for ( i = 1; i <= N; i++ )
{
while ( !Qmin.empty() && Qmin.front() < i - L + 1 )
Qmin.pop_front();
while ( !Qmin.empty() && minim[i][j] < minim[Qmin.back()][j] )
Qmin.pop_back();
Qmin.push_back(i);
while ( !Qmax.empty() && Qmax.front() < i - L + 1 )
Qmax.pop_front();
while ( !Qmax.empty() && maxim[i][j] > maxim[Qmax.back()][j] )
Qmax.pop_back();
Qmax.push_back(i);
// printf( "v:%d %d %d %d\n", i, j, maxim[Qmax.front()][j], minim[Qmin.front()][j] );
if ( i >= L && j >= C )
{
d = maxim[Qmax.front()][j] - minim[Qmin.front()][j];
if ( d < dif )
{
dif = d;
var = 1;
}
else
if ( d == dif )
var++;
}
}
}
}
void Get( int& x )
{
for ( ; r[p] < '0' || r[p] > '9'; Next() );
for ( x = 0; r[p] >= '0' && r[p] <= '9'; Next() )
{
x = ( x * 10 ) + ( r[p] - '0' );
}
}
void Next()
{
if ( ++p == MAXREAD )
std::fread( r, 1, MAXREAD, stdin ), p = 0;
}
void Write( int a[MAXNM][MAXNM] )
{
int i, j;
for ( i = 1; i <= N; i++ )
{
for ( j = 1; j <= M; j++ )
printf( "%d ", a[i][j] );
printf( "\n" );
}
printf( "\n" );
}