Cod sursa(job #63552)

Utilizator devilkindSavin Tiberiu devilkind Data 29 mai 2007 14:34:08
Problema Struti Scor 30
Compilator c Status done
Runda Arhiva de probleme Marime 2.85 kb
#include <stdio.h>
#define filein "struti.in"
#define fileout "struti.out"
#define INFTY 30000
#define NMax 1000
typedef int matrix[NMax + 1][NMax + 1];
typedef struct {
				 int val;
				 int poz;
			   } entry;

int m, n, p;
matrix M;

int DX, DY;

entry st[NMax * NMax + 1];

int MIN[NMax + 1][NMax + 1], MAX[NMax + 1][NMax + 1], AUX[NMax + 1][NMax + 1];

entry compute(int DX, int DY)
{ int i, j, prim = 0, ultim = 0;
  entry X;

	// afla maximul pe portiuni dreptunghiulare...
	for (j = 1; j <= n; j++)
	{
		prim = ultim = 0; st[prim].val = 0; st[prim].poz = 0;
		for (i = 1; i <= m; i++)
		{
			while (prim <= ultim && st[prim].poz <= i-DX) 		prim++;
			while (ultim >= prim && st[ultim].val < M[i][j])    ultim--;
			st[++ultim].val = M[i][j]; st[ultim].poz = i;

			if (i >= DX)
				AUX[i-DX+1][j] = st[prim].val;

		}

	}

	for (i = 1; i <= m-DX+1; i++)
	{
		prim = ultim = 0; st[prim].val = 0; st[prim].poz = 0;
		for (j = 1; j <= n; j++)
		{
			while (prim <= ultim && st[prim].poz <= j-DY)		prim++;
			while (ultim >= prim && st[ultim].val < AUX[i][j])  ultim--;
			st[++ultim].val = AUX[i][j]; st[ultim].poz = j;

			if (j >= DY)
				MAX[i][j-DY+1] = st[prim].val;
		}

	}

	// afla minimul pe portiuni dreptunghiulare...
	for (j = 1; j <= n; j++)
	{
		prim = ultim = 0; st[prim].val = INFTY; st[prim].poz = 0;
		for (i = 1; i <= m; i++)
		{
			while (prim <= ultim && st[prim].poz <= i-DX) 		prim++;
			while (ultim >= prim && st[ultim].val > M[i][j])    ultim--;
			st[++ultim].val = M[i][j]; st[ultim].poz = i;

			if (i >= DX)
				AUX[i-DX+1][j] = st[prim].val;

		}

	}

	for (i = 1; i <= m-DX+1; i++)
	{
		prim = ultim = 0; st[prim].val = INFTY; st[prim].poz = 0;
		for (j = 1; j <= n; j++)
		{
			while (prim <= ultim && st[prim].poz <= j-DY)		prim++;
			while (ultim >= prim && st[ultim].val > AUX[i][j])  ultim--;
			st[++ultim].val = AUX[i][j]; st[ultim].poz = j;

			if (j >= DY)
				MIN[i][j-DY+1] = st[prim].val;
		}

	}

	// determina solutia...

	X.val = INFTY;
	for (i = 1; i <= m-DX+1; i++)
		for (j = 1; j <= n-DY+1; j++)
			if (MAX[i][j] - MIN[i][j] < X.val)
			{ X.val = MAX[i][j] - MIN[i][j]; X.poz = 1; }
			else if (MAX[i][j] - MIN[i][j] == X.val)
            	X.poz++;

	return X;
}

void solve()
{
	FILE *fin = fopen(filein, "r"), *fout = fopen(fileout, "w");
	int i, j; entry X, Y;

                fscanf(fin, "%d %d %d", &m, &n, &p);
		for (i = 1; i <= m; i++)
			for (j = 1; j <= n; j++)
				fscanf(fin, "%d", &M[i][j]);

		for (i = 1; i <= p; i++)
		{
			fscanf(fin, "%d %d", &DX, &DY);
			X = compute(DX, DY);
			if (DX != DY)
			{
				Y = compute(DY, DX);
				if (X.val < Y.val)			X = Y;
				else if (X.val == Y.val)    X.poz += Y.poz;
			}

			fprintf(fout, "%d %d\n", X.val, X.poz);
		}

	fclose(fin);
}

int main()
{
	solve();
	return 0;
}