Cod sursa(job #1466917)

Utilizator BLz0rDospra Cristian BLz0r Data 31 iulie 2015 20:53:26
Problema Struti Scor 90
Compilator cpp Status done
Runda Arhiva de probleme Marime 3.12 kb
#include <cstdio>
#include <algorithm>
#include <deque>
using namespace std;

#define Nmax 1002
#define inf 0x3f3f3f3f

FILE *f = fopen ( "struti.in", "r" );
FILE *g = fopen ( "struti.out", "w" );

int v[Nmax][Nmax], Min[Nmax][Nmax], Max[Nmax][Nmax];
int SolMin[Nmax][Nmax], SolMax[Nmax][Nmax];
deque < int > Dq;

int N, M, Q, x, y, Sol = inf, nrs = 0;

void ClearDeque(){
     while ( !Dq.empty() )
        Dq.pop_back();
}

void ResetAll (){

    Sol = inf; nrs = 0;
    for ( int i = 1; i <= N; ++i )
        for ( int j = 1; j <= M; ++j )
           Min[i][j] = Max[i][j] = SolMin[i][j] = SolMax[i][j] = 0;
}

void Solve (){

        for ( int j = 1; j <= M; ++j ){
            ClearDeque();
            for ( int i = 1; i <= N; ++i ){
                while ( !Dq.empty() && v[i][j] <= v[Dq.back()][j] )
                    Dq.pop_back();

                Dq.push_back(i);

                if ( Dq.front() <= i - x )
                    Dq.pop_front();

                if ( i >= x )
                    Min[i][j] = v[Dq.front()][j];
            }

            ClearDeque();

            for ( int i = 1; i <= N; ++i ){
                while ( !Dq.empty() && v[i][j] >= v[Dq.back()][j] )
                    Dq.pop_back();

                Dq.push_back(i);

                if ( Dq.front() <= i - x )
                    Dq.pop_front();

                if ( i >= x )
                    Max[i][j] = v[Dq.front()][j];
            }
        }

        for ( int i = 1; i <= N; ++i ){
            ClearDeque();
            for ( int j = 1; j <= M; ++j ){
                while ( !Dq.empty() && Min[i][j] <= Min[i][Dq.back()] )
                    Dq.pop_back();

                Dq.push_back(j);

                if ( Dq.front() <= j - y )
                    Dq.pop_front();

                if ( j >= y )
                    SolMin[i][j] = Min[i][Dq.front()];
            }

            ClearDeque();

            for ( int j = 1; j <= M; ++j ){
                while ( !Dq.empty() && Max[i][j] >= Max[i][Dq.back()] )
                    Dq.pop_back();

                Dq.push_back(j);

                if ( Dq.front() <= j - y )
                    Dq.pop_front();

                if ( j >= y )
                    SolMax[i][j] = Max[i][Dq.front()];
            }
        }

        for ( int i = x; i <= N; ++i ){
            for ( int j = y; j <= M; ++j ){
                if ( SolMax[i][j] - SolMin[i][j] < Sol ){
                    Sol = SolMax[i][j] - SolMin[i][j];
                    nrs = 1;
                }
                else if ( SolMax[i][j] - SolMin[i][j] == Sol )
                    nrs++;
            }
        }
}

int main(){

    fscanf ( f, "%d%d%d", &N, &M, &Q );

    for ( int i = 1; i <= N; ++i )
        for ( int j = 1; j <= M; ++j )
            fscanf ( f, "%d", &v[i][j] );

    while ( Q-- ){

        fscanf ( f, "%d%d", &x, &y );

        ResetAll();
        Solve();

        if ( x != y ){
            swap (x,y);
            Solve();
        }

        fprintf ( g, "%d %d\n", Sol, nrs );

    }

    return 0;
}