Cod sursa(job #264383)

Utilizator vlad_DVlad Dumitriu vlad_D Data 21 februarie 2009 23:01:41
Problema Struti Scor 0
Compilator cpp Status done
Runda Arhiva de probleme Marime 3.96 kb
/*
PROB: struti de pe infoarena.ro

cu deque...uri

*/

#include <cstdio>

using namespace std;
int N, M, i, j, P;
int v[1024][1024];

#define NMAX 1001
struct nod{
	int val, id;
	nod(int _val, int _id) {val = _val; id = _id;}
	nod(){};
	};
nod dq[2500][1001];
int folosite = 0;	
struct deque {
      public:
             deque() {
                     id = folosite;
                     folosite++;
                     head = 0;
                     afterTail = 0;
                     }
             bool empty() {
                  return head == afterTail;
                  }
             void clear() {
                  head = afterTail = 0;
                  }
             void pop_front() {
                  ++head; 
                  if (head == NMAX) head = 0;
                  }
             void pop_back() {
                  --afterTail;
                  if (afterTail == -1) afterTail+=NMAX;
                  }
             nod &front() {
                 return dq[id][head];
                 }
             nod &back() {
                 if (afterTail == 0) return dq[id][NMAX-1];        
                 return dq[id][afterTail - 1];
                 }
             void push_front(nod X) {
                  --head;
                  if (head == -1) head+=NMAX;
                  dq[id][head] = X;
                  }
             
      private:
              int id;
              int head;
              int afterTail;
      };

int main() {
    freopen ("struti.in", "r", stdin);
	freopen("struti.out", "w", stdout);
	scanf("%d %d %d\n", &N, &M, &P);

	char c[10000];
	for (i=1; i<=N; i++) {
		gets(c);
		j = 0; int k = 1;
		int nr = 0;
		for (j=0; c[j]; j++){
			if (c[j] == ' ') {
				//printf("%d %d %d\n",i, k, nr);	
				v[i][k] = nr; k++; nr = 0; continue;}
			nr*=10; nr+=c[j]-'0';
			}
		//printf("%d %d %d\n",i, k, nr);
		v[i][k] = nr;
		
	}
    deque YMAX[1001], YMIN[1001];
    
	while(P--) {
		int DX, DY;
		int da = 2;
		int MIN = 9000, NR = 0;	
		scanf("%d %d", &DX, &DY);
        
		while (da--) {
			if (da == 0 && DX == DY) break;
			int aux = DX; DX = DY; DY = aux;
			for (j = 1; j <= M; ++j) YMAX[j].clear(), YMIN[j].clear();
        
			for (i=1; i<=N; i++) {
				deque XMAX, XMIN;
				for (j=1; j<=M; j++) {
					nod X, BAG;
					//printf("aha");
					while (!YMAX[j].empty()) 
						{
						X = YMAX[j].front();
						if (X.val < v[i][j]) YMAX[j].pop_front();
						else break;
						}
					YMAX[j].push_front(nod(v[i][j], i));
					//bag element
					X = YMAX[j].back();
					if (X.id == i - DX) YMAX[j].pop_back();
					//scot batran
					while (!YMIN[j].empty()) {
						X = YMIN[j].front();
						if (X.val > v[i][j]) YMIN[j].pop_front();
						else break;
						}
					YMIN[j].push_front(nod(v[i][j], i));
					X = YMIN[j].back();
					if (X.id == i - DX) YMIN[j].pop_back();
					//la j se baga asta;;
					BAG = YMAX[j].back();
					BAG.id = j;
					//scot mai 
					while (!XMAX.empty()) {
						X = XMAX.front();
						if (X.val < BAG.val) XMAX.pop_front();
						else break;
						}
					//bag element
					XMAX.push_front(BAG);
					//scot batran
					X = XMAX.back();
					if (X.id == j - DY) XMAX.pop_back();
					BAG = YMIN[j].back();
					BAG.id = j;
					while (!XMIN.empty()) {
						X = XMIN.front();
						if (X.val > BAG.val) XMIN.pop_front();
						else break;
						}
					XMIN.push_front(BAG);
					//scot batran
					X = XMIN.back();
					if (X.id == j - DY) XMIN.pop_back();
					//for j
					if (i >= DX && j >= DY) {
						int AN = 0 ;
						X = XMIN.back();
						//printf("%d ", X.val);
						AN-=X.val;
						X = XMAX.back();
						AN+=X.val;
					//	printf("%d ", X.val);
					//	printf("%d %d\n\n", i, j);
						if (AN < MIN ) {MIN = AN; NR = 0;}
						if (AN == MIN) ++NR;
						}
					}
				//for i
				} 

			//shile da
			}
		printf("%d %d\n", MIN, NR);
		//while
		} 
	return 0;
}