Cod sursa(job #775776)

Utilizator contdetestareTester contdetestare Data 8 august 2012 21:04:09
Problema Struti Scor 80
Compilator cpp Status done
Runda Arhiva de probleme Marime 2.88 kb
#include <iostream>
#include <fstream>
#include <deque>

using namespace std;

ifstream f("struti.in");
ofstream g("struti.out");

#define nmax 1003
#define inf (1<<30)

int m, n, P, a[nmax][nmax], Min[nmax][nmax], Max[nmax][nmax];

int rez, cate;

void citeste(){

	f >> m >> n >> P;//
	for(int i=1; i<=m; i++){
        for(int j=1; j<=n; j++) f >> a[i][j];
	}

}

void afla(int X, int Y){

    //X = x e paralel cu axa Oy;
    // Y paralel cu axa Ox

    //aflu pentru fiecare secventa de X elemente din fiecare coloana Minimul, respectiv Maximul
    //m = nr de linii; si n = nr de coloane
    for(int j=1; j<=n; j++){
        deque<int> dq_min,dq_max;
        for(int i=1; i<=m; i++){
            //minimul
            while(dq_min.size() && a[i][j] < a[ dq_min.back() ][j]) dq_min.pop_back();
            dq_min.push_back(i);

            while(dq_min.size() && dq_min.front()+X-1 < i) dq_min.pop_front();
            Min[i][j] = a[ dq_min.front() ][j];

            //maximul
            while(dq_max.size() && a[i][j] > a[ dq_max.back() ][j]) dq_max.pop_back();
            dq_max.push_back(i);

            while(dq_max.size() && dq_max.front()+X-1 < i) dq_max.pop_front();
            Max[i][j] = a[ dq_max.front() ][j];
        }
    }

    //acum aflu pentru fiecare linie (pe care se termin un drepunghi) adica de la X in jos; si pentru fiecare secventa de Y elemente de pe fiecare linie
    //aflue Min rescpectiv Max

    for(int i=X; i<=m; i++){
        deque<int> dq_min,dq_max;
        for(int j=1; j<=n; j++){
            //minimul
            while(dq_min.size() && Min[i][j] < Min[i][ dq_min.back() ]) dq_min.pop_back();
            dq_min.push_back(j);

            while(dq_min.size() && dq_min.front()+Y-1 < j) dq_min.pop_front();

            //maximul
            while(dq_max.size() && Max[i][j] > Max[i][ dq_max.back() ]) dq_max.pop_back();
            dq_max.push_back(j);

            while(dq_max.size() && dq_max.front()+Y-1 < j) dq_max.pop_front();

            if (j >= Y){//daca am un dreptunghi cu coltul dreapta jos in (i,j)
                int x = Min[i][ dq_min.front() ];
                int y = Max[i][ dq_max.front() ];
                if (y - x < rez){
                    rez = y - x;
                    cate = 1;
                }else if (y - x == rez){
                    ++cate;
                }
            }
        }
    }

}

void rezolva(){

    //citesc P perechi de dimensiuni de dreptunghiuri; trebuie sa caut un dreptunghi care are diferenta intre Max si Min cat mai mica

    for(int i=1; i<=P; i++){
        int X, Y;
        f >> X >> Y;
        rez = inf;
        cate = 0;
        afla(X,Y);

        if (X != Y)afla(Y,X);
        g << rez << " " << cate << "\n";
    }

}

int main(){

    citeste();
    rezolva();

    f.close();
    g.close();

    return 0;

}