Pagini recente » Cod sursa (job #1094371) | Cod sursa (job #2313060) | Cod sursa (job #1190552) | Cod sursa (job #2631439) | Cod sursa (job #597855)
Cod sursa(job #597855)
#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;
}