Cod sursa(job #1081810)

Utilizator R.A.RFMI Romila Remus Arthur R.A.R Data 13 ianuarie 2014 21:57:14
Problema Struti Scor 100
Compilator cpp Status done
Runda Teme Pregatire ACM Unibuc 2013 Marime 3.18 kb
#include <fstream>
#include <deque>

using namespace std;

const int NMAX = 1100;

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

int V[NMAX][NMAX], n, m, p, x, y, maxValue[NMAX][NMAX], minValue[NMAX][NMAX], bestSolution, solutionCounter;

void calculateMaxValue(int k){ // calculeaza maximul de pe coloane intr-o matrice maxValue
    deque<int> maxL;
    int i,j;

    for (j=1; j<=n; j++){

        maxL.clear();

        for (i=1; i<=m; i++){


            while (!maxL.empty() && V[maxL.back()][j] <= V[i][j]) maxL.pop_back();
            maxL.push_back(i);

            while (!maxL.empty() && maxL.front() <= i-k) maxL.pop_front();

            if (i >= k )
                maxValue[i-k+1][j] = V[maxL.front()][j];

        }

        //for (int h=i-k; h<=m; h++)
        //  maxValue[h][j] = V[maxL.front()][j];
    }
}

void calculateMinValue(int k){ // calcuelaza minimul de pe coloane intr-o matrice minValue
    deque<int> minL;
    int i,j;

    for (j=1; j<=n; j++){

        minL.clear();

        for (i=1; i<=m; i++){


            while (!minL.empty() && V[minL.back()][j] >= V[i][j]) minL.pop_back();
            minL.push_back(i);

            while (!minL.empty() && minL.front() <= i-k) minL.pop_front();

            if (i >= k )
                minValue[i-k+1][j] = V[minL.front()][j];

        }

        //for (int h=i-k; h<=m; h++)
        //  minValue[h][j] = V[minL.front()][j];
    }
}

void getSolution(int x, int y){

    deque<int> maxValueDeq, minValueDeq;

    calculateMinValue(y);// calcuelaza minimul de pe coloane intr-o matrice minValue
    calculateMaxValue(y);// calculeaza maximul de pe coloane intr-o matrice maxValue

    for (int i=1; i<=m-y+1; i++){

        maxValueDeq.clear();
        minValueDeq.clear();

        for (int j=1; j<=n; j++){

            while (!minValueDeq.empty() && minValue[i][minValueDeq.back()] >= minValue[i][j]) minValueDeq.pop_back();
            minValueDeq.push_back(j);

            while (!maxValueDeq.empty() && maxValue[i][maxValueDeq.back()] <= maxValue[i][j]) maxValueDeq.pop_back();
            maxValueDeq.push_back(j);

            while (!minValueDeq.empty() && minValueDeq.front() <= j-x) minValueDeq.pop_front();
            while (!maxValueDeq.empty() && maxValueDeq.front() <= j-x) maxValueDeq.pop_front();

            if (j >= x){
                if (maxValue[i][maxValueDeq.front()] - minValue[i][minValueDeq.front()] < bestSolution)
                    bestSolution = maxValue[i][maxValueDeq.front()] - minValue[i][minValueDeq.front()], solutionCounter = 1;
                else
                    if (maxValue[i][maxValueDeq.front()] - minValue[i][minValueDeq.front()] == bestSolution) solutionCounter++;
            }

        }

    }
}

int main(){

    int i,j,k,x,y;

    in>>m>>n>>p;

    for (int i=1; i<= m; i++)
        for (int j=1; j<=n; j++)
            in>>V[i][j];

    for (k=1; k<=p; k++){

        in>>x>>y;

        bestSolution = NMAX * NMAX; solutionCounter = 0;

        if (x!=y){

            getSolution(x,y);
            getSolution(y,x);

            out<<bestSolution<<" "<<solutionCounter<<"\n";

        } else {
            getSolution(x,y);

            out<<bestSolution<<" "<<solutionCounter<<"\n";
        }
    }
}