Cod sursa(job #1443740)

Utilizator depevladVlad Dumitru-Popescu depevlad Data 28 mai 2015 16:21:05
Problema Struti Scor 100
Compilator cpp Status done
Runda Arhiva de probleme Marime 4.49 kb
#include <cstdio>
#include <algorithm>
#include <cstring>
#include <deque>

using namespace std;

#define inFile "struti.in"
#define outFile "struti.out"
#define MAX_N 1000

FILE *in = fopen(inFile, "r");
FILE *out = fopen(outFile, "w");

int Min[MAX_N + 1][MAX_N + 1];
int Max[MAX_N + 1][MAX_N + 1];
int A[MAX_N + 1][MAX_N + 1];
deque < int > slwMin, slwMax;

void resetMinMax() {
    memset(Min, -1, sizeof(Min[0][0]) * (MAX_N+1) * (MAX_N+1));
    memset(Max, -1, sizeof(Max[0][0]) * (MAX_N+1) * (MAX_N+1));
    slwMin.clear();
    slwMax.clear();
}

void getSlw(int dx, int j, int n) {
    int i;
    slwMin.clear();
    slwMax.clear();
    for(i = 1; i <= dx; i++) {
        while(!slwMin.empty() && A[slwMin.back()][j] >= A[i][j])
            slwMin.pop_back();
        while(!slwMax.empty() && A[slwMax.back()][j] <= A[i][j])
            slwMax.pop_back();
        slwMin.push_back(i);
        slwMax.push_back(i);
    }
    Min[1][j] = A[slwMin.front()][j];
    Max[1][j] = A[slwMax.front()][j];
    for(i = dx+1; i <= n; i++) {
        if(!slwMin.empty() && slwMin.front() <= i-dx)
            slwMin.pop_front();
        if(!slwMax.empty() && slwMax.front() <= i-dx)
            slwMax.pop_front();
        while(!slwMin.empty() && A[slwMin.back()][j] >= A[i][j])
            slwMin.pop_back();
        while(!slwMax.empty() && A[slwMax.back()][j] <= A[i][j])
            slwMax.pop_back();
        slwMin.push_back(i);
        slwMax.push_back(i);
        Min[i-dx+1][j] = A[slwMin.front()][j];
        Max[i-dx+1][j] = A[slwMax.front()][j];
    }
}

void getMinMax(int n, int m, int dx) {
    resetMinMax();
    for(int j = 1; j <= m; j++)
        getSlw(dx, j, n);
}

int minDif, minDifCount;

void getLine(int m, int dy, int i) {
    int j;
    slwMin.clear();
    slwMax.clear();
    //fprintf(out, "Line %d\n", i);
    for(j = 1; j <= dy; j++) {
        while(!slwMin.empty() && Min[i][j] <= Min[i][slwMin.back()])
            slwMin.pop_back();
        while(!slwMax.empty() && Max[i][j] >= Max[i][slwMax.back()])
            slwMax.pop_back();
        slwMin.push_back(j);
        slwMax.push_back(j);
    }
    if(Max[i][slwMax.front()] - Min[i][slwMin.front()] < minDif)
            minDif = Max[i][slwMax.front()] - Min[i][slwMin.front()], minDifCount = 1;
        else if(Max[i][slwMax.front()] - Min[i][slwMin.front()] == minDif)
            minDifCount++;
    j--;
    //fprintf(out, "REPORTING ... Min is %d -- %d , Max is %d -- %d for rectangle from %d to %d WITH DIFF %d\n", Min[i][slwMin.front()], slwMin.front(), Max[i][slwMax.front()], slwMax.front(), j-dy+1, j, Max[i][slwMax.front()] - Min[i][slwMin.front()]);
    for(j = dy+1; j <= m; j++) {
    //fprintf(out, "REPORTING ... Min is %d -- %d , Max is %d -- %d for rectangle from %d to %d WITH DIFF %d\n", Min[i][slwMin.front()], slwMin.front(), Max[i][slwMax.front()], slwMax.front(), j-dy+1, j, Max[i][slwMax.front()] - Min[i][slwMin.front()]);
        if(!slwMin.empty() && slwMin.front() <= j-dy)
            slwMin.pop_front();
        if(!slwMax.empty() && slwMax.front() <= j-dy)
            slwMax.pop_front();
        while(!slwMin.empty() && Min[i][j] <= Min[i][slwMin.back()])
            slwMin.pop_back();
        while(!slwMax.empty() && Max[i][j] >= Max[i][slwMax.back()])
            slwMax.pop_back();
        slwMin.push_back(j);
        slwMax.push_back(j);
        if(Max[i][slwMax.front()] - Min[i][slwMin.front()] < minDif)
            minDif = Max[i][slwMax.front()] - Min[i][slwMin.front()], minDifCount = 1;
        else if(Max[i][slwMax.front()] - Min[i][slwMin.front()] == minDif)
            minDifCount++;
    }
    //fprintf(out, "\n-----------\n");
}

void getMatrix(int n, int m, int dx, int dy) {
    //fprintf(out, "GETTING RESULT FOR MATRIX: %d is DX %d is DY\n", dx, dy);
    for(int i = 1; i <= n-dx+1; i++)
        getLine(m, dy, i);
}

void solve(int dx, int dy, int n, int m) {
    getMinMax(n, m, dx);
    getMatrix(n, m, dx, dy);
    if(dx == dy) return;
    getMinMax(n, m, dy);
    getMatrix(n, m, dy, dx);
}

int main() {
    int n, m, i, j, testCase, dx, dy;

    fscanf(in, "%d %d %d", &n, &m, &testCase);
    for(i = 1; i <= n; i++)
        for(j = 1; j <= m; j++)
            fscanf(in, "%d", &A[i][j]);

    while(testCase--) {
        fscanf(in, "%d %d", &dx, &dy);
        minDif = 0x7fffffff;
        minDifCount = -1;
        solve(dx, dy, n, m);
        fprintf(out, "%d %d\n", minDif, minDifCount);
    }

    return 0;
}