Pagini recente » Cod sursa (job #2805047) | Cod sursa (job #1081607) | Cod sursa (job #551594) | Cod sursa (job #3231209) | Cod sursa (job #775776)
Cod sursa(job #775776)
#include <iostream>
#include <fstream>
#include <deque>
using namespace std;
ifstream f("struti.in");
ofstream g("struti.out");
#define nmax 1003
#define inf (1<<30)
int m, n, P, a[nmax][nmax], Min[nmax][nmax], Max[nmax][nmax];
int rez, cate;
void citeste(){
f >> m >> n >> P;//
for(int i=1; i<=m; i++){
for(int j=1; j<=n; j++) f >> a[i][j];
}
}
void afla(int X, int Y){
//X = x e paralel cu axa Oy;
// Y paralel cu axa Ox
//aflu pentru fiecare secventa de X elemente din fiecare coloana Minimul, respectiv Maximul
//m = nr de linii; si n = nr de coloane
for(int j=1; j<=n; j++){
deque<int> dq_min,dq_max;
for(int i=1; i<=m; i++){
//minimul
while(dq_min.size() && a[i][j] < a[ dq_min.back() ][j]) dq_min.pop_back();
dq_min.push_back(i);
while(dq_min.size() && dq_min.front()+X-1 < i) dq_min.pop_front();
Min[i][j] = a[ dq_min.front() ][j];
//maximul
while(dq_max.size() && a[i][j] > a[ dq_max.back() ][j]) dq_max.pop_back();
dq_max.push_back(i);
while(dq_max.size() && dq_max.front()+X-1 < i) dq_max.pop_front();
Max[i][j] = a[ dq_max.front() ][j];
}
}
//acum aflu pentru fiecare linie (pe care se termin un drepunghi) adica de la X in jos; si pentru fiecare secventa de Y elemente de pe fiecare linie
//aflue Min rescpectiv Max
for(int i=X; i<=m; i++){
deque<int> dq_min,dq_max;
for(int j=1; j<=n; j++){
//minimul
while(dq_min.size() && Min[i][j] < Min[i][ dq_min.back() ]) dq_min.pop_back();
dq_min.push_back(j);
while(dq_min.size() && dq_min.front()+Y-1 < j) dq_min.pop_front();
//maximul
while(dq_max.size() && Max[i][j] > Max[i][ dq_max.back() ]) dq_max.pop_back();
dq_max.push_back(j);
while(dq_max.size() && dq_max.front()+Y-1 < j) dq_max.pop_front();
if (j >= Y){//daca am un dreptunghi cu coltul dreapta jos in (i,j)
int x = Min[i][ dq_min.front() ];
int y = Max[i][ dq_max.front() ];
if (y - x < rez){
rez = y - x;
cate = 1;
}else if (y - x == rez){
++cate;
}
}
}
}
}
void rezolva(){
//citesc P perechi de dimensiuni de dreptunghiuri; trebuie sa caut un dreptunghi care are diferenta intre Max si Min cat mai mica
for(int i=1; i<=P; i++){
int X, Y;
f >> X >> Y;
rez = inf;
cate = 0;
afla(X,Y);
if (X != Y)afla(Y,X);
g << rez << " " << cate << "\n";
}
}
int main(){
citeste();
rezolva();
f.close();
g.close();
return 0;
}