Cod sursa(job #1464740)

Utilizator borcanirobertBorcani Robert borcanirobert Data 24 iulie 2015 14:14:11
Problema Struti Scor 100
Compilator cpp Status done
Runda Arhiva de probleme Marime 3.56 kb
#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" );
}