Cod sursa(job #1467023)

Utilizator BLz0rDospra Cristian BLz0r Data 2 august 2015 17:03:38
Problema Struti Scor 100
Compilator cpp Status done
Runda Arhiva de probleme Marime 3.74 kb
#include <fstream>
#include <algorithm>
#include <deque>
#include <string>
using namespace std;

#define Nmax 1002
#define inf 0x3f3f3f3f

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

ifstream fin  ( "struti.in" );
ofstream fout ( "struti.out" );

string Buffer;
string :: iterator BufIt;

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;

int ReadInt (){

    int nr = 0;

    while ( *BufIt < '0' || *BufIt > '9' )
        ++BufIt;

    while ( *BufIt >= '0' && *BufIt <= '9' ){
        nr = nr * 10 + ( *BufIt - '0' );
        ++BufIt;
    }

    return nr;
}


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(){

    getline ( fin, Buffer, (char)0 );
    BufIt = Buffer.begin();

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

    N = ReadInt();
    M = ReadInt();
    Q = ReadInt();

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

    while ( Q-- ){

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

        x = ReadInt();
        y = ReadInt();

        ResetAll();
        Solve();

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

        fout << Sol << " " << nrs << '\n';
        //fprintf ( g, "%d %d\n", Sol, nrs );

    }

    return 0;
}