Pagini recente » Cod sursa (job #1301138) | Cod sursa (job #2280569) | Cod sursa (job #502042) | Cod sursa (job #1301279) | Cod sursa (job #778370)
Cod sursa(job #778370)
#include <iostream>
#include <fstream>
using namespace std;
ifstream f("struti.in");
ofstream g("struti.out");
#define nmax 1003
#define inf (1<<30)
#define Cifmax 5000000
int m, n, P;
short int a[nmax][nmax], Min[nmax][nmax], Max[nmax][nmax];
int dq_min[nmax], dq_max[nmax];
int rez, cate;
char S[Cifmax];
int poz;
short int query[10][2];
inline void citeste_buf(short int &nr){
nr = 0;
for(; S[poz]<'0' || S[poz]>'9'; poz++);
for(; S[poz]>='0' && S[poz]<='9'; poz++){
nr = nr * 10 + (S[poz] - '0');
}
}
void citeste(){
f >> m >> n >> P;//
f.get();
f.getline(S, Cifmax, EOF);//iau tot fisierul
for(int i=1; i<=m; i++){
for(int j=1; j<=n; j++){
citeste_buf(a[i][j]);
}
}
/*
for(int i=1; i<=m; i++){
for(int j=1; j<=n; j++) f >> a[i][j];
}
*/
}
inline void deck_pe_coloana(const int &i,const int &j, int &St, int &Dr,const int &X,const int &cod){
if (cod == -1){//pt minim
while(St<=Dr && a[i][j] < a[ dq_min[Dr] ][j]) --Dr;
dq_min[++Dr] = i;
//while(St<=Dr && dq_min[St] + X-1 < i) ++St;
if (dq_min[St] + X-1 < i) ++St;
Min[i][j] = a[ dq_min[St] ][j];
}else if (cod == 1){//pt max
while(St<=Dr && a[i][j] > a[ dq_max[Dr] ][j]) --Dr;
dq_max[++Dr] = i;
//while(St<=Dr && dq_max[St]+X-1 < i) ++St;
if (dq_max[St]+X-1 < i) ++St;
Max[i][j] = a[ dq_max[St] ][j];
}
}
inline void deck_pe_linie(const int &i, const int &j, int &St, int &Dr,const int &X,const int &cod){
if (cod == -1){//pt minim
while(St <= Dr && Min[i][j] < Min[i][ dq_min[Dr] ]) --Dr;
dq_min[++Dr] = j;
//while(St<=Dr && dq_min[St] + X-1 < j) ++St;
if (dq_min[St] + X-1 < j) ++St;
}else if(cod == 1){
while(St <= Dr && Max[i][j] > Max[i][ dq_max[Dr] ]) --Dr;
dq_max[++Dr] = j;
//while(St <= Dr && dq_max[St]+X-1 < j) ++St;
if (dq_max[St]+X-1 < j) ++St;
}
}
inline void afla(const int &X, const 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++){
int St_min = 1;
int Dr_min = 0;
int St_max = 1;
int Dr_max = 0;
for(int i=1; i<=m; i++){
//minimul
deck_pe_coloana(i, j, St_min, Dr_min, X, -1);
//maximul
deck_pe_coloana(i, j, St_max, Dr_max, X, 1);
}
}
//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++){
int St_min = 1; int Dr_min = 0;
int St_max = 1; int Dr_max = 0;
for(int j=1; j<=n; j++){
//minimul
deck_pe_linie(i, j, St_min, Dr_min, Y, -1);
//maximul
deck_pe_linie(i, j, St_max, Dr_max, Y, 1);
if (j >= Y){
int x = Min[i][ dq_min[St_min] ];
int y = Max[i][ dq_max[St_max] ];
x = y - x;
if( x < rez){
rez = x;
cate = 1;
}else if (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++){
short int X, Y;
query[i][0] = X;
query[i][1] = Y;
}
for(int i=1; i<=P; i++){
short int X, Y;
X = query[i][0];
Y = query[i][1];
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;
}