Cod sursa(job #2025512)

Utilizator Alex18maiAlex Enache Alex18mai Data 22 septembrie 2017 19:39:51
Problema Struti Scor 60
Compilator cpp Status done
Runda Arhiva de probleme Marime 5.97 kb
#include <fstream>

using namespace std;

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

struct node{
    int nr;
    node *prev = NULL;
    node *next = NULL;
};

class Deque{
    int size = 0;
    node *pos_front = NULL;
    node *pos_back = NULL;
public:
    bool empty(){
        if (size == 0){
            return 1;
        }
        return 0;
    };
    void push_front(int val){
        size ++;
        node *now = new node();
        now -> nr = val;
        if (pos_front != NULL){
            now -> prev = pos_front;
            pos_front -> next = now;
        }
        pos_front = now;
        if (pos_back == NULL){
            pos_back = now;
        }
    };
    void push_back(int val){
        size ++;
        node *now = new node();
        now -> nr = val;
        if (pos_back != NULL){
            now -> next = pos_back;
            pos_back -> prev = now;
        }
        pos_back = now;
        if (pos_front == NULL){
            pos_front = now;
        }
    };
    void pop_front(){
        if (pos_front == NULL){
            return;
        }
        size --;
        if (pos_front -> prev != NULL){
            pos_front = pos_front -> prev;
            delete pos_front -> next;
            pos_front -> next = NULL;
        }
        else{
            delete pos_front;
            pos_front = NULL;
            pos_back = NULL;
        }
    };
    void pop_back(){
        if (pos_back == NULL){
            return;
        }
        size --;
        if (pos_back -> next != NULL){
            pos_back = pos_back -> next;
            delete pos_back -> prev;
            pos_back -> prev = NULL;
        }
        else{
            delete pos_back;
            pos_front = NULL;
            pos_back = NULL;
        }
    };
    int front(){
        return pos_front -> nr;
    };
    int back(){
        return pos_back -> nr;
    };
    int sz(){
        return size;
    }
} Q;

int mat[1100][1100];
int MIN[1100][1100];
int MAX[1100][1100];
int scad1[1100][1100];
int scad2[1100][1100];
int n , m , p;

void golire(){
    while(!Q.empty()){
        Q.pop_front();
    }
}

void make_min (int x , int y){
    for (int i=1; i<=n; i++){
        for (int j=1; j<=x; j++){
            while ( !Q.empty() && mat[i][Q.back()] > mat[i][j]){
                Q.pop_back();
            }
            Q.push_back(j);
        }
        MIN[i][1] = mat[i][Q.front()];
        for (int j=x + 1; j<=m; j++){
            if (Q.front() == j - x){
                Q.pop_front();
            }
            while ( !Q.empty() && mat[i][Q.back()] > mat[i][j]){
                Q.pop_back();
            }
            Q.push_back(j);
            MIN[i][j - x + 1] = mat[i][Q.front()];
        }
        golire();
    }
    for (int j=1; j<=m - x + 1; j++){
        for (int i=1; i<=y; i++){
            while ( !Q.empty() && MIN[Q.back()][j] > MIN[i][j]){
                Q.pop_back();
            }
            Q.push_back(i);
        }
        MIN[1][j] = MIN[Q.front()][j];
        for (int i=y + 1; i<=n; i++){
            if (Q.front() == i - y){
                Q.pop_front();
            }
            while ( !Q.empty() && MIN[Q.back()][j] > MIN[i][j]){
                Q.pop_back();
            }
            Q.push_back(i);
            MIN[i - y + 1][j] =MIN[Q.front()][j];
        }
        golire();
    }
}

void make_max (int x , int y){
    for (int i=1; i<=n; i++){
        for (int j=1; j<=x; j++){
            while ( !Q.empty() && mat[i][Q.back()] < mat[i][j]){
                Q.pop_back();
            }
            Q.push_back(j);
        }
        MAX[i][1] = mat[i][Q.front()];
        for (int j=x + 1; j<=m; j++){
            if (Q.front() == j - x){
                Q.pop_front();
            }
            while ( !Q.empty() && mat[i][Q.back()] < mat[i][j]){
                Q.pop_back();
            }
            Q.push_back(j);
            MAX[i][j - x + 1] = mat[i][Q.front()];
        }
        golire();
    }
    for (int j=1; j<=m - x + 1; j++){
        for (int i=1; i<=y; i++){
            while ( !Q.empty() && MAX[Q.back()][j] < MAX[i][j]){
                Q.pop_back();
            }
            Q.push_back(i);
        }
        MAX[1][j] = MAX[Q.front()][j];
        for (int i=y + 1; i<=n; i++){
            if (Q.front() == i - y){
                Q.pop_front();
            }
            while ( !Q.empty() && MAX[Q.back()][j] < MAX[i][j]){
                Q.pop_back();
            }
            Q.push_back(i);
            MAX[i - y + 1][j] =MAX[Q.front()][j];
        }
        golire();
    }
}

void scad_1(int y , int x, int &Min){
    for (int i=1; i<=n - x  +1; i++){
        for (int j=1; j<=m - y + 1; j++){
            scad1[i][j] = MAX[i][j] - MIN[i][j];
            Min = min(Min , scad1[i][j]);
        }
    }
}

void caut_1(int y , int x, int &cont , int Min){
    for (int i=1; i<=n - x  +1; i++){
        for (int j=1; j<=m - y + 1; j++){
            if (scad1[i][j] == Min){
                cont++;
            }
        }
    }
}

void scad_2(int y , int x, int &Min){
    for (int i=1; i<=n - x  +1; i++){
        for (int j=1; j<=m - y + 1; j++){
            scad2[i][j] = MAX[i][j] - MIN[i][j];
            Min = min(Min , scad2[i][j]);
        }
    }
}

void caut_2(int y , int x, int &cont , int Min){
    for (int i=1; i<=n - x  +1; i++){
        for (int j=1; j<=m - y + 1; j++){
            if (scad2[i][j] == Min){
                cont++;
            }
        }
    }
}

int main() {

    ios::sync_with_stdio(false);
    cin.tie(NULL);

    cin>>n>>m>>p;
    for (int i=1; i<=n; i++){
        for (int j=1; j<=m; j++){
            cin>>mat[i][j];
        }
    }
    for (int i=1; i<=p; i++){
        int x , y;
        cin>>x>>y;
        make_min(x , y);
        make_max(x , y);
        int Min = 1000000000;
        scad_1(x , y , Min);
        make_min(y , x);
        make_max(y , x);
        scad_2(y , x , Min);
        int cont = 0;
        caut_1(x , y , cont , Min);
        if (x != y){
            caut_2(y , x , cont , Min);
        }
        cout<<Min<<" "<<cont<<'\n';
    }
    return 0;
}