Cod sursa(job #2858018)

Utilizator gripzStroescu Matei Alexandru gripz Data 26 februarie 2022 20:28:42
Problema Struti Scor 0
Compilator cpp-64 Status done
Runda Arhiva de probleme Marime 3.34 kb
#include <iostream>
#include <climits>
#include <deque>

#define MAXN 1002

using namespace std;

int N, M, P, m[MAXN][MAXN], minL[MAXN][MAXN], maxL[MAXN][MAXN];
deque<int> smallest, biggest;
int R = INT_MAX, reps;

void solve(int w, int h) {
    for(int i = 1; i <= N; i++) {
        smallest.clear();
        biggest.clear();
        smallest.push_front(1);
        biggest.push_front(1);
        for(int j = 2; j <= M; j++) {
            if(smallest.front() < j - w + 1)
                smallest.pop_front();
            if(smallest.back() < j - w + 1)
                smallest.pop_back();

            if(biggest.front() < j - w + 1)
                biggest.pop_front();
            if(biggest.back() < j - w + 1)
                biggest.pop_back();

            if(smallest.size() == 2) {
                if(m[i][smallest.front()] > m[i][j]) {
                    smallest.push_front(j);
                    smallest.pop_back();
                } else if(m[i][smallest.back()] > m[i][j]) {
                    smallest.pop_back();
                    smallest.push_back(j);
                }
            } else {
                int nr = smallest.front();
                if(m[i][j] < m[i][nr])
                    smallest.push_front(j);
                else
                    smallest.push_back(j);
            }

            if(biggest.size() == 2) {
                if(m[i][biggest.front()] < m[i][j]) {
                    biggest.push_front(j);
                    biggest.pop_back();
                } else if(m[i][biggest.back()] < m[i][j]) {
                    biggest.pop_back();
                    biggest.push_back(j);
                }
            } else {
                int nr = biggest.front();
                if(m[i][j] > m[i][nr])
                    biggest.push_front(j);
                else
                    biggest.push_back(j);
            }

            if(j >= w) {
                minL[i][j - w + 1] = smallest.front();
                //printf("%d ", minL[i][j - w + 1]);
            }

            if(j >= w) {
                maxL[i][j - w + 1] = biggest.front();
         //       printf("%d ", maxL[i][j - w + 1]);
            }
        }
       // printf("\n");
    }

    for(int i = 1; i <= N - h + 1; i++) {
        for(int j = 1; j <= M - w + 1; j++) {
            int minim = INT_MAX;
            int maxim = -1;
            for(int k = i; k <= i + h - 1; k++) {
                minim = min(minim, m[k][minL[k][j]]);
                maxim = max(maxim, m[k][maxL[k][j]]);
            }
            int diff = maxim - minim;
            if(R > diff) {
                R = diff;
                reps = 0;
            } else if(R == diff) {
                reps++;
            }
        }
    }
}


int main()
{

    freopen("struti.in", "r", stdin);
    freopen("struti.out", "w", stdout);

    cin >>  N >> M >> P;
    for(int i = 1; i <= N; i++) {
        for(int j = 1; j <= M; j++) {
            scanf("%d", &m[i][j]);
        }
    }

    for(int i = 1; i <= P; i++) {
        int w, h;
        scanf("%d %d", &w, &h);
        if(w != h) {
            solve(w, h);
            solve(h, w);
        } else {
            solve(w, h);
        }
        printf("%d %d\n", R, reps);
        R = INT_MAX;
        reps = 0;
    }


    return 0;
}