Cod sursa(job #452665)

Utilizator vladiiIonescu Vlad vladii Data 10 mai 2010 18:40:05
Problema Struti Scor 40
Compilator cpp Status done
Runda Arhiva de probleme Marime 8.6 kb
#include <iostream>
#include <deque>
using namespace std;
#define nmax 1010

int N, M, A[nmax][nmax];
int P, DX, DY;
int MAX[nmax][nmax], MAX2[nmax][nmax];
int MIN[nmax][nmax], MIN2[nmax][nmax];
deque<pair<int, int> > deq;

int main() {
    FILE *f1=fopen("struti.in", "r"), *f2=fopen("struti.out", "w");
    int i, j, p, q;
    fscanf(f1, "%d %d %d\n", &M, &N, &P);
    for(i=1; i<=N; i++) {
         for(j=1; j<=M; j++) {
              fscanf(f1, "%d", &A[i][j]);
         }
    }
    while(P--) {
         int minim = 99999999, nr = 0;
         fscanf(f1, "%d %d\n", &DX, &DY);
         //calculeaza MAX si MAX2
         deq.clear();
         for(i=1; i<=M; i++) {
              for(j=1; j<=DX; j++) {
                   while(!deq.empty() && deq.back().first <= A[i][j]) {
                        deq.pop_back();
                   }
                   deq.push_back(make_pair(A[i][j], j));
              }
              MAX[i][1] = deq.front().first;
              for(j=DX + 1; j<=N; j++) {
                   while(!deq.empty() && deq.back().first <= A[i][j]) {
                        deq.pop_back();
                   }
                   while(!deq.empty() && deq.front().second <= (j - DX)) {
                        deq.pop_front();
                   }
                   deq.push_back(make_pair(A[i][j], j));
                   MAX[i][j - DX + 1] = deq.front().first;
              }
              deq.clear();
         }
         for(i=1; i<=N; i++) {
              for(j=1; j<=DY; j++) {
                   while(!deq.empty() && deq.back().first <= MAX[j][i]) {
                        deq.pop_back();
                   }
                   deq.push_back(make_pair(MAX[j][i], j));
              }
              MAX2[1][i] = deq.front().first;
              for(j=DY + 1; j<=M; j++) {
                   while(!deq.empty() && deq.back().first <= MAX[j][i]) {
                        deq.pop_back();
                   }
                   while(!deq.empty() && deq.front().second <= (j - DY)) {
                        deq.pop_front();
                   }
                   deq.push_back(make_pair(MAX[j][i], j));
                   MAX2[j - DY + 1][i] = deq.front().first;
              }
              deq.clear();
         }
         //calculeaza MIN si MIN2
         for(i=1; i<=M; i++) {
              for(j=1; j<=DX; j++) {
                   while(!deq.empty() && deq.back().first >= A[i][j]) {
                        deq.pop_back();
                   }
                   deq.push_back(make_pair(A[i][j], j));
              }
              MIN[i][1] = deq.front().first;
              for(j=DX + 1; j<=N; j++) {
                   while(!deq.empty() && deq.back().first >= A[i][j]) {
                        deq.pop_back();
                   }
                   while(!deq.empty() && deq.front().second <= (j - DX)) {
                        deq.pop_front();
                   }
                   deq.push_back(make_pair(A[i][j], j));
                   MIN[i][j - DX + 1] = deq.front().first;
              }
              deq.clear();
         }
         for(i=1; i<=N; i++) {
              for(j=1; j<=DY; j++) {
                   while(!deq.empty() && deq.back().first >= MIN[j][i]) {
                        deq.pop_back();
                   }
                   deq.push_back(make_pair(MIN[j][i], j));
              }
              MIN2[1][i] = deq.front().first;
              for(j=DY + 1; j<=M; j++) {
                   while(!deq.empty() && deq.back().first >= MIN[j][i]) {
                        deq.pop_back();
                   }
                   while(!deq.empty() && deq.front().second <= (j - DY)) {
                        deq.pop_front();
                   }
                   deq.push_back(make_pair(MIN[j][i], j));
                   MIN2[j - DY + 1][i] = deq.front().first;
              }
              deq.clear();
         }
         for(i=1; i<=M - DY + 1; i++) {
              for(j=1; j<=N - DX + 1; j++) {
                   if(MAX2[i][j] - MIN2[i][j] < minim) {
                        minim = MAX2[i][j] - MIN2[i][j];
                        nr = 1;
                   }
                   else if(MAX2[i][j] - MIN2[i][j] == minim) {
                        nr++;
                   }
              }
         }
         if(DX!=DY) {
              swap(DX, DY);
              deq.clear();
              for(i=1; i<=M; i++) {
                   for(j=1; j<=DX; j++) {
                        while(!deq.empty() && deq.back().first <= A[i][j]) {
                             deq.pop_back();
                        }
                        deq.push_back(make_pair(A[i][j], j));
                   }
                   MAX[i][1] = deq.front().first;
                   for(j=DX + 1; j<=N; j++) {
                        while(!deq.empty() && deq.back().first <= A[i][j]) {
                             deq.pop_back();
                        }
                        while(!deq.empty() && deq.front().second <= (j - DX)) {
                             deq.pop_front();
                        }
                        deq.push_back(make_pair(A[i][j], j));
                        MAX[i][j - DX + 1] = deq.front().first;
                   }
                   deq.clear();
              }
              for(i=1; i<=N; i++) {
                   for(j=1; j<=DY; j++) {
                        while(!deq.empty() && deq.back().first <= MAX[j][i]) {
                             deq.pop_back();
                        }
                        deq.push_back(make_pair(MAX[j][i], j));
                   }
                   MAX2[1][i] = deq.front().first;
                   for(j=DY + 1; j<=M; j++) {
                        while(!deq.empty() && deq.back().first <= MAX[j][i]) {
                             deq.pop_back();
                        }
                        while(!deq.empty() && deq.front().second <= (j - DY)) {
                             deq.pop_front();
                        }
                        deq.push_back(make_pair(MAX[j][i], j));
                        MAX2[j - DY + 1][i] = deq.front().first;
                   }
                   deq.clear();
              }        
              //calculeaza MIN si MIN2
              for(i=1; i<=M; i++) {
                   for(j=1; j<=DX; j++) {
                        while(!deq.empty() && deq.back().first >= A[i][j]) {
                             deq.pop_back();
                        }
                        deq.push_back(make_pair(A[i][j], j));
                   }
                   MIN[i][1] = deq.front().first;
                   for(j=DX + 1; j<=N; j++) {
                        while(!deq.empty() && deq.back().first >= A[i][j]) {
                             deq.pop_back();
                        }
                        while(!deq.empty() && deq.front().second <= (j - DX)) {
                             deq.pop_front();
                        }
                        deq.push_back(make_pair(A[i][j], j));
                        MIN[i][j - DX + 1] = deq.front().first;
                   }
                   deq.clear();
              }
              for(i=1; i<=N; i++) {
                   for(j=1; j<=DY; j++) {
                        while(!deq.empty() && deq.back().first >= MIN[j][i]) {
                             deq.pop_back();
                        }
                        deq.push_back(make_pair(MIN[j][i], j));
                   }
                   MIN2[1][i] = deq.front().first;
                   for(j=DY + 1; j<=M; j++) {
                        while(!deq.empty() && deq.back().first >= MIN[j][i]) {
                             deq.pop_back();
                        }
                        while(!deq.empty() && deq.front().second <= (j - DY)) {
                             deq.pop_front();
                        }
                        deq.push_back(make_pair(MIN[j][i], j));
                        MIN2[j - DY + 1][i] = deq.front().first;
                   }
                   deq.clear();
              }
              for(i=1; i<=M - DY + 1; i++) {
                   for(j=1; j<=N - DX + 1; j++) {
                        if(MAX2[i][j] - MIN2[i][j] < minim) {
                             minim = MAX2[i][j] - MIN2[i][j];
                             nr = 1;
                        }
                        else if(MAX2[i][j] - MIN2[i][j] == minim) {
                             nr++;
                        }
                   }
              }
         }
         fprintf(f2, "%d %d\n", minim, nr);
    }
    
    fclose(f1); fclose(f2);
    return 0;
}